¿Es buena idea estos índices?

12/02/2004 - 12:24 por Naimps | Informe spam
Muy buenas.

Supongo que haría falta más información, pero haber si más o menos esto
basta. Tengo las siguientes tablas:

billetes (140000 registros):
id int identity (1, 1) not null,
fecha smalldatetime not null,
ida int not null,
vuelta int not null,
estado char(1) not null,
agencia smallint not null,
usuario tinyint not null

pasajero (140000 registros):
id int identity (1, 1) not null,
nombre varchar (50) not null
tarifa_ida smallint not null,
tarifa_vuelta smallint not null,
billetes_id int not null

coche:
id int identity (1, 1) not null,
matricula varchar (10) not null
tarifa smallint not null,
billetes_id int not null

animal:
id int identity (1, 1) not null,
tarifa tinyint not null,
billetes_id int not null

viajes:
id int identity(1, 1) not null,
linea tinyint not null,
fecha smalldatetime,
hora datetime

Un billete tiene un único pasajero y/o un único coche y/o un único animal.

La tabla billetes se busca, para una consulta de previsión de embarque, por
el estado (igual a E), y por la ida y vuelta (claves externas de una tabla
que contiene los viajes).

La tabla de pasajero está ligada a la de billetes (billetes_id) a una única
tabla de tarifas (tarifa_ida indica la tarifa de la ida y tarifa_vuelta la
de la vuelta).

Y lo mismo con las de vehículos y animales.

Yo había pensado, en la de de viajes, crear el PK en id, y luego una
agrupada con "fecha, linea" (¿o mejor "linea, fecha"?).

En la de billetes, PK para id, y luego una agrupada: "ida, vuelta, estado"
(para optimizar la búsqueda por fechas de salida y estado).

¿Es buena idea? ¿O una tontería?

Gracias.

Preguntas similare

Leer las respuestas

#11 Javier Loria
12/02/2004 - 21:48 | Informe spam
Hola:
Los "logical reads" es lo que quieres optimizar, lo del "physical reads"
en realidad significa que fueron leidos del disco, (la siguiente vez seran
"logical reads" porque estaran en el cache; y lo del "read-ahead" significa
que previendo su uso se leyeron fisicamente mas de los extrictamente
necesarios, con la intencion de tenerlos en cache.
El que se redujeran implica una mejora en el desempeno pero no se si es
claro que esta mejora es "trivial" con respecto a la tabla: IC_VIABIL que es
la que realmente esta produciendo las lecturas y la que deberias tratar de
"optimizar".
Saludos,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.


Naimps" <"@naimps@ <"@naimps@"@terra.es> escribio:
On Thu, 12 Feb 2004 07:47:34 -0600, Javier Loria wrote:

Hola:
El uso de un Indice adicional sobre la tabla viajes, dependera
de la cantidad de filas que tenga esta tabla, si son menos de 20,000
proablemente no vale la pena agregar ningun indice, porque las filas
son lo suficientemente pequenas. Me parece que son como 5000 filas
por Extension (grupos de 8 paginas de 8 Kb).
Si son mas filas, los indices dependeran del forma en que se
consulten los datos y de los datos mismos. Particularmente si hay
pocas lineas (menos de 10/20) es probable que un indice sobre este
campo no se use mucho. Fecha-Linea o Fecha-Hora-Linea serian
candidatos, e incluso es posible que sea mejor definirlos como
Clustered Index (Indice Compuesto), pero esto depende de la
aplicacion. En la tabla de billetes parece mala idea usar estado
ya que seguramente solo tiene 2 valores, y las columnas poco
selectivas no son ultiles para los indices. Una llave Ida-Id y otra
Vuelta-ID parecieran mejores opciones. Estas opiniones deben ser
comprobadas con datos, pero serian las
primeras opciones que buscaria.
No voy a comentar sobre el diseno de la Tablas ni sobre el uso del
Identity, pero de ninguna manera significa que los apruebe :(.

Saludos,


Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.


Naimps" <"@naimps@ <"@naimps@"@terra.es> escribio:
Muy buenas.

Supongo que haría falta más información, pero haber si más o menos
esto basta. Tengo las siguientes tablas:

billetes (140000 registros):
id int identity (1, 1) not null,
fecha smalldatetime not null,
ida int not null,
vuelta int not null,
estado char(1) not null,
agencia smallint not null,
usuario tinyint not null

pasajero (140000 registros):
id int identity (1, 1) not null,
nombre varchar (50) not null
tarifa_ida smallint not null,
tarifa_vuelta smallint not null,
billetes_id int not null

coche:
id int identity (1, 1) not null,
matricula varchar (10) not null
tarifa smallint not null,
billetes_id int not null

animal:
id int identity (1, 1) not null,
tarifa tinyint not null,
billetes_id int not null

viajes:
id int identity(1, 1) not null,
linea tinyint not null,
fecha smalldatetime,
hora datetime

Un billete tiene un único pasajero y/o un único coche y/o un único
animal.

La tabla billetes se busca, para una consulta de previsión de
embarque, por el estado (igual a E), y por la ida y vuelta (claves
externas de una tabla que contiene los viajes).

La tabla de pasajero está ligada a la de billetes (billetes_id) a
una única tabla de tarifas (tarifa_ida indica la tarifa de la ida y
tarifa_vuelta la de la vuelta).

Y lo mismo con las de vehículos y animales.

Yo había pensado, en la de de viajes, crear el PK en id, y luego una
agrupada con "fecha, linea" (¿o mejor "linea, fecha"?).

En la de billetes, PK para id, y luego una agrupada: "ida, vuelta,
estado" (para optimizar la búsqueda por fechas de salida y estado).

¿Es buena idea? ¿O una tontería?

Gracias.





Acabo de añadir los índices que me comentas, y al ejecutar al
consulta obtengo estos valores:

Antes índice:
Table 'ic_barco'. Scan count 16, logical reads 32, physical reads 0,
read-ahead reads 0.
Table 'ic_acomodaciones'. Scan count 16, logical reads 32, physical
reads 0, read-ahead reads 0.
Table 'ic_numaco'. Scan count 32, logical reads 256, physical reads 0,
read-ahead reads 0.
Table 'ic_viabil'. Scan count 4, logical reads 4824, physical reads 0,
read-ahead reads 0.
Table 'ic_billetes'. Scan count 6, logical reads 2243, physical reads
0, read-ahead reads 0.
Table 'ic_viaje'. Scan count 8, logical reads 32, physical reads 0,
read-ahead reads 0.
Table 'ic_viagrup'. Scan count 8, logical reads 16, physical reads 0,
read-ahead reads 0.
Table '#0A8AE248'. Scan count 4, logical reads 4, physical reads 0,
read-ahead reads 0.

Después índices:
Table 'ic_barco'. Scan count 6, logical reads 12, physical reads 0,
read-ahead reads 0.
Table 'ic_acomodaciones'. Scan count 6, logical reads 12, physical
reads 0, read-ahead reads 0.
Table 'ic_numaco'. Scan count 12, logical reads 122, physical reads 0,
read-ahead reads 7.
Table 'ic_viabil'. Scan count 2, logical reads 2410, physical reads 1,
read-ahead reads 1202.
Table 'ic_billetes'. Scan count 8, logical reads 108, physical reads
4, read-ahead reads 2.
Table 'ic_viaje'. Scan count 8, logical reads 16, physical reads 0,
read-ahead reads 0.
Table 'ic_viagrup'. Scan count 8, logical reads 16, physical reads 0,
read-ahead reads 0.
Table '#17E4DD66'. Scan count 4, logical reads 4, physical reads 0,
read-ahead reads 0.

Los "logical reads" ha disminuido en varias tablas (enntre ellas
"billetes"), pero han aparecido en "physical reads" y en "read-ahead
reads". ¿Es bueno o malo? ¿Qué significan?

Gracias.
Respuesta Responder a este mensaje
#12 Adrian D. Garcia
13/02/2004 - 01:15 | Informe spam
Los physical reads significan que las paginas necesarias para resolver la
consulta no estaban en memoria. Seguramente si vuelves a lanzar el mismo
query veras que los physical reads se ponen a 0 asi que no te preocupes por
ello.
En cuanto a read-ahead significan la cantidad de paginas puestas en el cache
por el query.

En tiempos totales, si ejecutas uno y otro query, ves y notas alguna
diferencia? Creo que seguramente si.

Saludos
Adrian D. Garcia
MCSD
NDSoft Consultoria y Desarrollo

"Naimps" <"@naimps@"@terra.es> wrote in message
news:1huw9xnrmcsuc$.8ff3q61sfvz6$
On Thu, 12 Feb 2004 09:48:05 -0300, Maximiliano D. A. wrote:

> Sin conocer mas datos, no parece nada malo esos indices, igual te


aconsejo
> que al hacer la instruccion Sql que haga la consulta, revises muy bien


el
> plan de ejecucion.
>
> Salu2

Acabo de añadir el índice agrupado (ida, vuelta, estado), y al ejecutar al
consulta obtengo estos valores:

Antes índice:
Table 'ic_barco'. Scan count 16, logical reads 32, physical reads 0,
read-ahead reads 0.
Table 'ic_acomodaciones'. Scan count 16, logical reads 32, physical reads
0, read-ahead reads 0.
Table 'ic_numaco'. Scan count 32, logical reads 256, physical reads 0,
read-ahead reads 0.
Table 'ic_viabil'. Scan count 4, logical reads 4824, physical reads 0,
read-ahead reads 0.
Table 'ic_billetes'. Scan count 6, logical reads 2243, physical reads 0,
read-ahead reads 0.
Table 'ic_viaje'. Scan count 8, logical reads 32, physical reads 0,
read-ahead reads 0.
Table 'ic_viagrup'. Scan count 8, logical reads 16, physical reads 0,
read-ahead reads 0.
Table '#0A8AE248'. Scan count 4, logical reads 4, physical reads 0,
read-ahead reads 0.

Después índices:
Table 'ic_barco'. Scan count 6, logical reads 12, physical reads 0,
read-ahead reads 0.
Table 'ic_acomodaciones'. Scan count 6, logical reads 12, physical reads


0,
read-ahead reads 0.
Table 'ic_numaco'. Scan count 12, logical reads 122, physical reads 0,
read-ahead reads 7.
Table 'ic_viabil'. Scan count 2, logical reads 2410, physical reads 1,
read-ahead reads 1202.
Table 'ic_billetes'. Scan count 8, logical reads 108, physical reads 4,
read-ahead reads 2.
Table 'ic_viaje'. Scan count 8, logical reads 16, physical reads 0,
read-ahead reads 0.
Table 'ic_viagrup'. Scan count 8, logical reads 16, physical reads 0,
read-ahead reads 0.
Table '#17E4DD66'. Scan count 4, logical reads 4, physical reads 0,
read-ahead reads 0.

Los "logical reads" ha disminuido en varias tablas (enntre ellas
"billetes"), pero han aparecido en "physical reads" y en "read-ahead
reads". ¿Es bueno o malo? ¿Qué significan?

Gracias.

Respuesta Responder a este mensaje
#13 Naimps
13/02/2004 - 13:43 | Informe spam
On Thu, 12 Feb 2004 14:48:33 -0600, Javier Loria wrote:

Hola:
Los "logical reads" es lo que quieres optimizar, lo del "physical reads"
en realidad significa que fueron leidos del disco, (la siguiente vez seran
"logical reads" porque estaran en el cache; y lo del "read-ahead" significa
que previendo su uso se leyeron fisicamente mas de los extrictamente
necesarios, con la intencion de tenerlos en cache.
El que se redujeran implica una mejora en el desempeno pero no se si es
claro que esta mejora es "trivial" con respecto a la tabla: IC_VIABIL que es
la que realmente esta produciendo las lecturas y la que deberias tratar de
"optimizar".
Saludos,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.


Naimps" <"@naimps@ <"@naimps@"@terra.es> escribio:
On Thu, 12 Feb 2004 07:47:34 -0600, Javier Loria wrote:

Hola:
El uso de un Indice adicional sobre la tabla viajes, dependera
de la cantidad de filas que tenga esta tabla, si son menos de 20,000
proablemente no vale la pena agregar ningun indice, porque las filas
son lo suficientemente pequenas. Me parece que son como 5000 filas
por Extension (grupos de 8 paginas de 8 Kb).
Si son mas filas, los indices dependeran del forma en que se
consulten los datos y de los datos mismos. Particularmente si hay
pocas lineas (menos de 10/20) es probable que un indice sobre este
campo no se use mucho. Fecha-Linea o Fecha-Hora-Linea serian
candidatos, e incluso es posible que sea mejor definirlos como
Clustered Index (Indice Compuesto), pero esto depende de la
aplicacion. En la tabla de billetes parece mala idea usar estado
ya que seguramente solo tiene 2 valores, y las columnas poco
selectivas no son ultiles para los indices. Una llave Ida-Id y otra
Vuelta-ID parecieran mejores opciones. Estas opiniones deben ser
comprobadas con datos, pero serian las
primeras opciones que buscaria.
No voy a comentar sobre el diseno de la Tablas ni sobre el uso del
Identity, pero de ninguna manera significa que los apruebe :(.

Saludos,


Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.


Naimps" <"@naimps@ <"@naimps@"@terra.es> escribio:
Muy buenas.

Supongo que haría falta más información, pero haber si más o menos
esto basta. Tengo las siguientes tablas:

billetes (140000 registros):
id int identity (1, 1) not null,
fecha smalldatetime not null,
ida int not null,
vuelta int not null,
estado char(1) not null,
agencia smallint not null,
usuario tinyint not null

pasajero (140000 registros):
id int identity (1, 1) not null,
nombre varchar (50) not null
tarifa_ida smallint not null,
tarifa_vuelta smallint not null,
billetes_id int not null

coche:
id int identity (1, 1) not null,
matricula varchar (10) not null
tarifa smallint not null,
billetes_id int not null

animal:
id int identity (1, 1) not null,
tarifa tinyint not null,
billetes_id int not null

viajes:
id int identity(1, 1) not null,
linea tinyint not null,
fecha smalldatetime,
hora datetime

Un billete tiene un único pasajero y/o un único coche y/o un único
animal.

La tabla billetes se busca, para una consulta de previsión de
embarque, por el estado (igual a E), y por la ida y vuelta (claves
externas de una tabla que contiene los viajes).

La tabla de pasajero está ligada a la de billetes (billetes_id) a
una única tabla de tarifas (tarifa_ida indica la tarifa de la ida y
tarifa_vuelta la de la vuelta).

Y lo mismo con las de vehículos y animales.

Yo había pensado, en la de de viajes, crear el PK en id, y luego una
agrupada con "fecha, linea" (¿o mejor "linea, fecha"?).

En la de billetes, PK para id, y luego una agrupada: "ida, vuelta,
estado" (para optimizar la búsqueda por fechas de salida y estado).

¿Es buena idea? ¿O una tontería?

Gracias.





Acabo de añadir los índices que me comentas, y al ejecutar al
consulta obtengo estos valores:

Antes índice:
Table 'ic_barco'. Scan count 16, logical reads 32, physical reads 0,
read-ahead reads 0.
Table 'ic_acomodaciones'. Scan count 16, logical reads 32, physical
reads 0, read-ahead reads 0.
Table 'ic_numaco'. Scan count 32, logical reads 256, physical reads 0,
read-ahead reads 0.
Table 'ic_viabil'. Scan count 4, logical reads 4824, physical reads 0,
read-ahead reads 0.
Table 'ic_billetes'. Scan count 6, logical reads 2243, physical reads
0, read-ahead reads 0.
Table 'ic_viaje'. Scan count 8, logical reads 32, physical reads 0,
read-ahead reads 0.
Table 'ic_viagrup'. Scan count 8, logical reads 16, physical reads 0,
read-ahead reads 0.
Table '#0A8AE248'. Scan count 4, logical reads 4, physical reads 0,
read-ahead reads 0.

Después índices:
Table 'ic_barco'. Scan count 6, logical reads 12, physical reads 0,
read-ahead reads 0.
Table 'ic_acomodaciones'. Scan count 6, logical reads 12, physical
reads 0, read-ahead reads 0.
Table 'ic_numaco'. Scan count 12, logical reads 122, physical reads 0,
read-ahead reads 7.
Table 'ic_viabil'. Scan count 2, logical reads 2410, physical reads 1,
read-ahead reads 1202.
Table 'ic_billetes'. Scan count 8, logical reads 108, physical reads
4, read-ahead reads 2.
Table 'ic_viaje'. Scan count 8, logical reads 16, physical reads 0,
read-ahead reads 0.
Table 'ic_viagrup'. Scan count 8, logical reads 16, physical reads 0,
read-ahead reads 0.
Table '#17E4DD66'. Scan count 4, logical reads 4, physical reads 0,
read-ahead reads 0.

Los "logical reads" ha disminuido en varias tablas (enntre ellas
"billetes"), pero han aparecido en "physical reads" y en "read-ahead
reads". ¿Es bueno o malo? ¿Qué significan?

Gracias.





Gracias por las respuestas.

Para determinar si la consulta es buena o peor, utilizo el plan de
ejecución para ver los índices que utiliza, y después las estadísticas para
intentar reducir los las "logical reads".

¿Está bien o hay otra herramienta mejor?

Lo que no tengo claro, son todos los datos que devuelve el plan de
ejecución por cada nodo (Costo de CPU estimado, Costo de subárbol estimado,
E/S estimadas, Nº de ejecuciones, Nº de repeticiones, ...).

Lo pruebo directamente sobre la BDD de producción.
Respuesta Responder a este mensaje
#14 Javier Loria
13/02/2004 - 15:34 | Informe spam
Hola:
La tecnica que usas es buena y en general funciona muy bien.
Si quieres algo mucho mas "fuerte" puedes capturar la operacion "normal"
de 1 dia normal y optimizarla. Los pasos seria mas o menos asi:
a) Hacer un respaldo completo de la BD de produccion. (Punto de Inicio).
b) Capturar las sentencias que se le envian desde la aplicacion al
servidor con el Profiler. (Movimiento Diario).
c) Restaurar la BD en un servidor de pruebas y borrar todos los indices
excepto los necesarios para mantener la integridad (Llaves Primarias y
UNIQUE's) y talvez algunos indices que sean muy obvios (Llaves Foraneas
entre tablas grandes principalmente, o si usas Llaves Primarias no Naturales
las Llaves Primarias Naturales).
d) Respaldar la BD de Pruebas. (Punto de Inicio sin Indices).
e) Correr el script del Movimiento Diario desde el Analizador de
Consultas, y de nuevo con el Profiler capturas y separar las consultas mas
lentas y las mas frecuentes. NO tienes que optimizar todo, generalmente si
usas la regla 80/20 funciona bien, (Optimizas el 20% de las consultas mas
usadas y el 20% de las consultas mas lentas).
f) Tomas estas consultas y con el Analizador de Consultas utilizas el
"INDEX TUNNING WIZZARD" para que sugiera Indices. (SCRIPT de Nuevos
Indices).
g) Restaurar la BD (Punto de Inicio sin Indices) en el servidor de
pruebas y aplicas los Nuevos Indices. Luego corres otra vez el script de
operacion y vuelves a revisar el desempeno de las consultas mas lentas. Si
es aceptable el desempeno puedes mover aplicar los cambios al servidor de
produccion, si no vuelves a optimizar 20% mas lento.


Gracias.

Gracias por las respuestas.

Para determinar si la consulta es buena o peor, utilizo el plan de
ejecución para ver los índices que utiliza, y después las
estadísticas para intentar reducir los las "logical reads".

¿Está bien o hay otra herramienta mejor?

Lo que no tengo claro, son todos los datos que devuelve el plan de
ejecución por cada nodo (Costo de CPU estimado, Costo de subárbol
estimado, E/S estimadas, Nº de ejecuciones, Nº de repeticiones, ...).

Lo pruebo directamente sobre la BDD de producción.
Respuesta Responder a este mensaje
#15 Javier Loria
13/02/2004 - 15:57 | Informe spam
Disculpa se me fue en Send en vez de un Save. :(

Hola :
La tecnica que usas es buena y en general funciona muy bien.
Si quieres algo mucho mas "fuerte" puedes capturar la operacion "normal"
de 1 dia normal y optimizarla. Los pasos seria mas o menos asi:
a) Hacer un respaldo completo de la BD de produccion. (Punto de Inicio).
b) Capturar las sentencias que se le envian desde la aplicacion al
servidor con el Profiler. (Movimiento Diario).
c) Restaurar la BD en un servidor de pruebas y borrar todos los indices
excepto los necesarios para mantener la integridad (Llaves Primarias y
UNIQUE's) y talvez algunos indices que sean muy obvios (Llaves Foraneas
entre tablas grandes principalmente, o si usas Llaves Primarias no Naturales
las Llaves Primarias Naturales).
d) Respaldar la BD de Pruebas. (Punto de Inicio sin Indices).
e) Correr el script del Movimiento Diario desde el Analizador de
Consultas, y de nuevo con el Profiler capturas y separar las consultas mas
lentas y las mas frecuentes. NO tienes que optimizar todo, generalmente si
usas la regla 80/20 funciona bien, (Optimizas el 20% de las consultas mas
usadas y el 20% de las consultas mas lentas).
f) Tomas estas consultas y con el Analizador de Consultas utilizas el
"INDEX TUNNING WIZZARD" para que sugiera Indices. (SCRIPT de Nuevos
Indices).
g) Restaurar la BD (Punto de Inicio sin Indices) en el servidor de
pruebas y aplicas los Nuevos Indices. Luego corres otra vez el script de
operacion y vuelves a revisar el desempeno de las consultas mas lentas. Si
es aceptable el desempeno puedes mover aplicar los cambios al servidor de
produccion, si no vuelves a optimizar 20% mas lento.
h) Cuando estas satisfecho con el desempeno o cuando no se producen
mejoras importantes, aplicas los "scripts de indices nuevos" a la BD de
Produccion.
Si NO es posible aplicar esta tecnica a el movimiento de todos los
usuarios, puedes serparar la operacion de una estacion/usuario y aplicar
esta tecnica.
Saludos,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

Gracias por las respuestas.

Para determinar si la consulta es buena o peor, utilizo el plan de
ejecución para ver los índices que utiliza, y después las
estadísticas para intentar reducir los las "logical reads".

¿Está bien o hay otra herramienta mejor?

Lo que no tengo claro, son todos los datos que devuelve el plan de
ejecución por cada nodo (Costo de CPU estimado, Costo de subárbol
estimado, E/S estimadas, Nº de ejecuciones, Nº de repeticiones, ...).

Lo pruebo directamente sobre la BDD de producción.
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida