La regla de la izquierda -- Indices

04/02/2009 - 08:16 por Normanmp | Informe spam
La regla de la izquierda -> Sé que esto funciona para MYSQL tengo dudas si es
tambien valido para SQL server, por lo que megustaria que me lo confirmarais:

Supongamos un INDEX usuario (id, name, adress), y una cláusula SELECT ...
WHERE NAME = x. Este Select no aprovechará el índice. Tampoco lo haría un
SELECT ... WHERE ID =X AND ADRESS = Y. Cualquier consulta que incluya una
columna parte del index sin incluir además las columnas a su izquierda, no
usará el indice.

Por tanto en nuestro ejemplo solo sacarian provecho del indice las consultas
SELECT ... WHERE ID = x, o WHERE ID = X AND NAME = y o WHERE ID = x AND NAME
= y AND ADRESS = Z

Gracias

Preguntas similare

Leer las respuestas

#11 Alejandro Mesa
10/02/2009 - 02:11 | Informe spam
Corrección:

El optimizador no podra usar las estadisticas de el indice (A, B, C), ni la
estadistica que creamos sobre (C), manual o automatica. SQL Server tendra que
crear otra estadistica nueva para poder estimar cardinalidad y analizar el
costo de usar ese indice.



El optimizador no podra usar las estadisticas de el indice (A, B, C), SQL
Server tendra que crear otra estadistica nueva para poder estimar
cardinalidad y analizar el
costo de usar ese indice.

AMB


"Alejandro Mesa" wrote:

Jose Mariano Alvarez,

La pregunta se refiere a si SQL Server usara el indice o no, si es que no se
usa la columna lider en la expresion de filtro en el predicado, y mi
respuesta fue que SQL Server no podra estimar este valor si la columna lider
de la clave no es usada. Cuando digo no podra estimar, me refiero a que con
las estadisticas existentes, no podra hacerlo y por tanto tendra que optar
por hacer un scan de la tabla o de el indice clustered, o para ampliar mas la
respuesta, tendra que crear nuevas estadisticas, no solo para "where cP0",
sino para "where B=? and c=?" o "where B = ?".

Si se agregan nuevas estadisticas, es debido a la falta de las mismas. Como
te demostre en el post anterior, si la opcion de creacion automatica de
estadisticas esta apagada, entonces SQL Server no tendra la mas minima idea
de que hay una fila que cumple con esa expresion.

No se porque mencionas la frase "cover index", puesto que un indice es
considerado como "covered o cubierto" si en el se encuentra toda la data
referenciada en la sentencia, incluyendo el predicado mas la lista de
columnas, y el indice que usas de ejemplo no es un "covered index" para la
sentencia que usastes, porque en tu lista de columnas (*) se incluye la
columna [descript] y esa columna no es parte de ese indice.

> >> ALTER TABLE dbo.POC_CoverIndex
> >> ADD CONSTRAINT PK_POC_CoverIndex PRIMARY KEY NONCLUSTERED (
> >> A,B,C
> >> )
> >> GO

Este indice no se considera "convered index" para la sentencia.

select *
from dbo.POC_CoverIndex
where C = 500;

Mi pregunta es:

Si la opcion de creacion automatica de estadisticas esta apagada, y ademas
esa estadistica no se creo de antemano, automatica o manualmente, como sabe
SQL Server que existe una fila que cumple con la expresion "where C = 500"?

Al menos sabemos que las estadisticas almacenadas sobre el indice (A, B, C)
no son de ayuda en este caso y eso es a lo que me referi en mi post.

No se porque asumes que esta opcion de creacion automatica de estadisticas
va a estar prendida siempre.

Por ultimo, si el predicado es:

...
where A = ? and C = ?;

o

...
where A = ? and B = ?;

o

...
where A = ? and B = ? and C = ?;

El optimizador no necesitara agregar una nueva estadistica para saber si
usar el indice o no.

Que crees que pasaria si al estar apagada la opcion AUTO_CREATE_STATISTICS,
cambiamos la expresion a:

...
where B = 1000 and C = 500;

El optimizador no podra usar las estadisticas de el indice (A, B, C), ni la
estadistica que creamos sobre (C), manual o automatica. SQL Server tendra que
crear otra estadistica nueva para poder estimar cardinalidad y analizar el
costo de usar ese indice.

Sin esas estadisticas, SQL Server no usara ese indice del todo.


AMB


Subject: Re: La regla de la izquierda -- Indices 2/9/2009 2:47 PM PST

By: Jose Mariano Alvarez In: microsoft.public.es.sqlserver


Alejandro, pues creo que la confusion es semantica ya que lo que exprese
coincide con lo que sucede y ademas es totalmente consistente con tu
razonamiento y con el mio. Simplemente nunca dije que la estadistica se
agregaba al indice sino que podia usar el indice como "cover index" haciendo
un INDEX SCAN sobre el mismo.

Simplemente creo que me mal-interpretaste:

La pregunta original fue:
Por tanto en nuestro ejemplo solo sacarian provecho del indice las consultas
SELECT ... WHERE ID = x, o WHERE ID = X AND NAME = y o WHERE ID = x AND NAME
= y AND ADRESS = Z

> En tu correo donde te autocorregias expresaste
> y por lo tanto se debera hacer un scan de la tabla o el indice clustered en
> caso de este existir.

> Lo cual a mi criterio no es correcto ya que no es lo que sucede

Como que no es lo que sucede, entonces que fue lo que demostre?

AMB


"Jose Mariano Alvarez" wrote:

> Alejandro, pues creo que la confusion es semantica ya que lo que exprese
> coincide con lo que sucede y ademas es totalmente consistente con tu
> razonamiento y con el mio. Simplemente nunca dije que la estadistica se
> agregaba al indice sino que podia usar el indice como "cover index" haciendo
> un INDEX SCAN sobre el mismo.
>
> Simplemente creo que me mal-interpretaste:
>
> La pregunta original fue:
> Por tanto en nuestro ejemplo solo sacarian provecho del indice las consultas
> SELECT ... WHERE ID = x, o WHERE ID = X AND NAME = y o WHERE ID = x AND NAME
> = y AND ADRESS = Z
>
> En tu correo donde te autocorregias expresaste
> y por lo tanto se debera hacer un scan de la tabla o el indice clustered en
> caso de este existir.
>
> Lo cual a mi criterio no es correcto ya que no es lo que sucede Esto lo
> exprese en mi correo y queria que se hiciera notar ya que no se si MySql lo
> puede aprovechar de la misma manera que SQL Server
>
> Lo que exprese fue:
> Alejandro, si la condicion sobre esa columna (c3 = ?) es muy convergente,
> supongamos en extremo 1 registro, y si la cantidad de paginas de la tabla es
> grande en comparacion al indice, va a hacer un index scan y luego el lookup
> ya que eso es menos costoso que el scan de la table. Si la cantidad de
> registros crece, va a llegar un punto que el costo que produce la estructura
> de los indices y la aleatorizacion de accesos del nonclustered index que va
> a preferir un acceso mediante un table scan.
>
> Nunca exprese que haria un INDEX SEEK para obtener 1 registro sino que
> implicitamente asumi que el SQL Server sabe que hay un solo registro. Aqui
> omiti expresar lo de las estadisticas generadas automaticamente asi como que
> me estaba refiriendo a un nonclustered index..
>
> Tu me respondiste
> Eso lo sabes tu, pero SQL Server no tiene idea de cuantos registros cumplen
> esa condicion en ese indice puesto que no hay estadisticas para saberlo y no
> va a tomar el riesgo de scanear el indice para luego hacer key lookup
>
> Por eso envie el ejemplo que no coincide con esta frase.
> Luego si exprese lo de las estadisticas en mi correo del ejemplo y tu lo
> reflejas en tu ultimo correo.
>
> Por lo tanto
> IMPORTANTE
> ***********************************************************************
> La respuesta exacta es NO, otras consultas
> tambien pueden sacar provecho del indice
> aun sin usar la regla de la izquierda.
> ***********************************************************************
>
> Creo que coincidimos luego de agregar los detalles que faltaban en las
> frases.
> Espero que les sirva a quienes lo leen ya que creo es bastante rico como
> ejemplo..
>
>
>
> Saludos
>
>
> Ing. Jose Mariano Alvarez
> SQLTotal Consulting
>
> (Cambia los ceros por O y saca lo que sobra)
>
> Este mensaje se proporciona tal como es, SIN GARANTIAS de ninguna clase. Por
> favor tratar de indicar la versión de SQL y Service Pack. La inclusión de
> (CREATE, INSERTS, etc.) para poder reproducir el problema también ayuda.
>
>
>
>
>
>
>
>
>
>
> "Alejandro Mesa" wrote in message
> news:
> > Jose Mariano Alvarez,
> >
> > Creo que tienes una confución aqui, o quizas sea yo quien la tenga, asi
> > que
> > vamos a tratar de averiguar como el optimizador determino que solo una
> > fila
> > macha esa expresion.
> >
> > Logicamente queel optimizador no saco esta conclusión de las estadisticas
> > normales de ese indice, pues como ya comente anteriormente, tenemos
> > estadiscas sobre la distribucion de valores de la columna lider, en este
> > caso
> > A, y tenemos valores de densidad para la combinacion de columnas de el
> > indice, combinacion de izquierda a derecha (A), (A, B), (A, B, C).
> >
> > DBCC SHOW_STATISTICS ('dbo.POC_CoverIndex', 'PK_POC_CoverIndex');
> > GO
> >
> > Entonces de donde saco el optimizador el valor estimado de el numero de
> > filas que cumplen la expresion?
> >
> > Bueno, si la base de datos tiene prendida la opción
> > "AUTO_CREATE_STATISTICS", la cual por lo general debe estar prendida,
> > entonces al analizar la consulta, este crea una estadistica para la
> > columna
> > C, pues no existe un indice que nos pueda proveer estadisticas sobre esta
> > columna por si sola. Al ver que solo una fila macha esta expresion,
> > entonces
> > decide scanear el indice nonclustered, que es mucho mas estrecho que la
> > tabla, pues solo contiene informacion sobre A, B, C y luego hace un lookup
> > en
> > la tabla para traer el valor de la columna [descrip]. Este plan es mucho
> > menos costoso que leer toda la tabla para encontrar la fila que macha con
> > esa
> > expresion, porque este puede estar al final de la tabla.
> >
> > Como podemos probar lo dicho?
> >
> > 1 - Apagamos la opcion AUTO_CREATE_STATISTICS en la db donde se hace la
> > prueba. Esto antes de ejecutar ela sentencia select.
> >
> > ALTER DATABASE prueba
> > SET AUTO_CREATE_STATISTICS OFF;
> > GO
> >
> > 2 - Para ser justo, actualizamos las estadisticas de el indice despues de
> > cargar la tabla.
> >
> > UPDATE STATISTICS dbo.POC_CoverIndex WITH FULLSCAN;
> > GO
> >
> > 3 - Ejecuta la senetencia select cuantas veces sea necesario, hasta que
> > estemos convencidos de lo que vemos, que es el scan de la tabla, pues no
> > tenemos estadisticas para determinar las filas que machan esa expresion.
> >
> > 4 - Prende la opcion, o en su lugar crea la estadistica a mano.
> >
> >
> > ALTER DATABASE prueba
> > SET AUTO_CREATE_STATISTICS ON;
> > GO
> >
> >
> > CREATE STATISTICS POC_CoverIndex_C
> > ON dbo.POC_CoverIndex(C) WITH FULLSCAN;
> > GO
> >
> > 5 - Limpia el cache de procedimientos por si acaso.
> >
> > DBCC freeproccache;
> > GO
> >
> > Fijate que tu mismo comentas sobre la estadistica generada automaticamente
> > sobre la columna C, en tu codigo de ejemplo. Pero eso no quiere decir que
> > el
> > optimizador puso esa estadistica en el indice, sino que creo una nueva
> > para
> > poder estimar expresiones sobre esa columna y la crea justo por eso,
> > porque
> > no tenia de donde sacar numero alguno para estimar la cardinalidad de la
> > expresion.
> >
> > Si miramos las estadisticas almacenadas en esta nueva estadistica que se
> > creo (valga aqui la redondancia):
> >
> > DBCC SHOW_STATISTICS ('dbo.POC_CoverIndex', 'POC_CoverIndex_C');
> > GO
> >
> > Vemos que la segunda fila en el histograma, dice que hay 9,997 filas en el
> > rango > 1 y <= 9999, que una fila tiene el valor de la columna C = 9999 y
> > que
> > 9997 de el resto de los valores son unicos. Por lo que podemos estimar que
> > solo una fila cumple la expresion C = 500.
> >
> >
> > Vuelvo a repetir, si el indice que tenemos es (A, B, C), en este caso
> > nonclustered, y ademas no tenemos indice clustered, y la expresion en el
> > predicado es:
> >
> > ...
> > where B = ?
> >
> > ó
Respuesta Responder a este mensaje
#12 Jose Mariano Alvarez
11/02/2009 - 02:19 | Informe spam
La pregunta se refiere a si SQL Server usara el indice o no, si es que no
se
usa la columna lider en la expresion de filtro en el predicado, y mi
respuesta fue que SQL Server no podra estimar este valor si la columna
lider
de la clave no es usada. Cuando digo no podra estimar, me refiero a que
con
las estadisticas existentes, no podra hacerlo y por tanto tendra que optar
por hacer un scan de la tabla o de el indice clustered, o para ampliar mas
la
respuesta, tendra que crear nuevas estadisticas, no solo para "where
cP0",
sino para "where B=? and c=?" o "where B = ?".



TOTALMENTE de acuerdo excepto que para que quede mas exacta cambiaria el
termino estadisticas existentes por estadisticas del indice.



Si se agregan nuevas estadisticas, es debido a la falta de las mismas.
Como
te demostre en el post anterior, si la opcion de creacion automatica de
estadisticas esta apagada, entonces SQL Server no tendra la mas minima
idea
de que hay una fila que cumple con esa expresion.



Totalmente de acuerdo


No se porque mencionas la frase "cover index", puesto que un indice es
considerado como "covered o cubierto" si en el se encuentra toda la data
referenciada en la sentencia, incluyendo el predicado mas la lista de
columnas, y el indice que usas de ejemplo no es un "covered index" para la
sentencia que usastes, porque en tu lista de columnas (*) se incluye la
columna [descript] y esa columna no es parte de ese indice.



Si es correcto.
Fue poco feliz porque no aclare que me referia a que era un cover index del
predicado de la clausula que podia satisfacer con un operador y no a la
sentencia propiamente dicha que es como se suele referir a un cover index.
..


>> ALTER TABLE dbo.POC_CoverIndex
>> ADD CONSTRAINT PK_POC_CoverIndex PRIMARY KEY NONCLUSTERED (
>> A,B,C
>> )
>> GO



Este indice no se considera "convered index" para la sentencia.

select *
from dbo.POC_CoverIndex
where C = 500;

Mi pregunta es:

Si la opcion de creacion automatica de estadisticas esta apagada, y ademas
esa estadistica no se creo de antemano, automatica o manualmente, como
sabe
SQL Server que existe una fila que cumple con la expresion "where C =
500"?

Al menos sabemos que las estadisticas almacenadas sobre el indice (A, B,
C)
no son de ayuda en este caso y eso es a lo que me referi en mi post.



En esae caso usa una heuristica y probablemente el porcentaje que considera
por la igualdad sin datos estadisticos haria que se resuelva el select
utilizando Scan de la tabla y en ese caso no usaria el indice..


No se porque asumes que esta opcion de creacion automatica de estadisticas
va a estar prendida siempre.

Por ultimo, si el predicado es:

...
where A = ? and C = ?;

o

...
where A = ? and B = ?;

o

...
where A = ? and B = ? and C = ?;

El optimizador no necesitara agregar una nueva estadistica para saber si
usar el indice o no.

Que crees que pasaria si al estar apagada la opcion
AUTO_CREATE_STATISTICS,
cambiamos la expresion a:

...
where B = 1000 and C = 500;

El optimizador no podra usar las estadisticas de el indice (A, B, C), ni
la
estadistica que creamos sobre (C), manual o automatica. SQL Server tendra
que
crear otra estadistica nueva para poder estimar cardinalidad y analizar el
costo de usar ese indice.

Sin esas estadisticas, SQL Server no usara ese indice del todo.




Ya corregiste esta afirmacion en tu siguiente correo.

Mi opinion es que existe una altisima posibilidad de que si la consulta es
trivial (como la que estamos considerando) haga lo mismo que antes de
agregar la condicion b=? bajo las mismas condiciones de contexto (o sea la
distribucuib de datos que genere en el ejemplo). Sino habria que considerar,
estadisticas sobre la columna B, sobr ela C, etc, etc para saber que va a
hacer el SQL y para coincidir contigo las estadisticas del indice compuesto
no servirian.
.


Saludos


Ing. Jose Mariano Alvarez
SQLTotal Consulting

(Cambia los ceros por O y saca lo que sobra)

Este mensaje se proporciona tal como es, SIN GARANTIAS de ninguna clase. Por
favor tratar de indicar la versión de SQL y Service Pack. La inclusión de
(CREATE, INSERTS, etc.) para poder reproducir el problema también ayuda.










"Alejandro Mesa" wrote in message
news:
Jose Mariano Alvarez,

La pregunta se refiere a si SQL Server usara el indice o no, si es que no
se
usa la columna lider en la expresion de filtro en el predicado, y mi
respuesta fue que SQL Server no podra estimar este valor si la columna
lider
de la clave no es usada. Cuando digo no podra estimar, me refiero a que
con
las estadisticas existentes, no podra hacerlo y por tanto tendra que optar
por hacer un scan de la tabla o de el indice clustered, o para ampliar mas
la
respuesta, tendra que crear nuevas estadisticas, no solo para "where
cP0",
sino para "where B=? and c=?" o "where B = ?".

Si se agregan nuevas estadisticas, es debido a la falta de las mismas.
Como
te demostre en el post anterior, si la opcion de creacion automatica de
estadisticas esta apagada, entonces SQL Server no tendra la mas minima
idea
de que hay una fila que cumple con esa expresion.

No se porque mencionas la frase "cover index", puesto que un indice es
considerado como "covered o cubierto" si en el se encuentra toda la data
referenciada en la sentencia, incluyendo el predicado mas la lista de
columnas, y el indice que usas de ejemplo no es un "covered index" para la
sentencia que usastes, porque en tu lista de columnas (*) se incluye la
columna [descript] y esa columna no es parte de ese indice.

>> ALTER TABLE dbo.POC_CoverIndex
>> ADD CONSTRAINT PK_POC_CoverIndex PRIMARY KEY NONCLUSTERED (
>> A,B,C
>> )
>> GO



Este indice no se considera "convered index" para la sentencia.

select *
from dbo.POC_CoverIndex
where C = 500;

Mi pregunta es:

Si la opcion de creacion automatica de estadisticas esta apagada, y ademas
esa estadistica no se creo de antemano, automatica o manualmente, como
sabe
SQL Server que existe una fila que cumple con la expresion "where C =
500"?

Al menos sabemos que las estadisticas almacenadas sobre el indice (A, B,
C)
no son de ayuda en este caso y eso es a lo que me referi en mi post.

No se porque asumes que esta opcion de creacion automatica de estadisticas
va a estar prendida siempre.

Por ultimo, si el predicado es:

...
where A = ? and C = ?;

o

...
where A = ? and B = ?;

o

...
where A = ? and B = ? and C = ?;

El optimizador no necesitara agregar una nueva estadistica para saber si
usar el indice o no.

Que crees que pasaria si al estar apagada la opcion
AUTO_CREATE_STATISTICS,
cambiamos la expresion a:

...
where B = 1000 and C = 500;

El optimizador no podra usar las estadisticas de el indice (A, B, C), ni
la
estadistica que creamos sobre (C), manual o automatica. SQL Server tendra
que
crear otra estadistica nueva para poder estimar cardinalidad y analizar el
costo de usar ese indice.

Sin esas estadisticas, SQL Server no usara ese indice del todo.


AMB


Subject: Re: La regla de la izquierda -- Indices 2/9/2009 2:47 PM PST

By: Jose Mariano Alvarez In: microsoft.public.es.sqlserver


Alejandro, pues creo que la confusion es semantica ya que lo que exprese
coincide con lo que sucede y ademas es totalmente consistente con tu
razonamiento y con el mio. Simplemente nunca dije que la estadistica se
agregaba al indice sino que podia usar el indice como "cover index"
haciendo
un INDEX SCAN sobre el mismo.

Simplemente creo que me mal-interpretaste:

La pregunta original fue:
Por tanto en nuestro ejemplo solo sacarian provecho del indice las
consultas
SELECT ... WHERE ID = x, o WHERE ID = X AND NAME = y o WHERE ID = x AND
NAME
= y AND ADRESS = Z

En tu correo donde te autocorregias expresaste
y por lo tanto se debera hacer un scan de la tabla o el indice clustered
en
caso de este existir.



Lo cual a mi criterio no es correcto ya que no es lo que sucede



Como que no es lo que sucede, entonces que fue lo que demostre?

AMB


"Jose Mariano Alvarez" wrote:

Alejandro, pues creo que la confusion es semantica ya que lo que exprese
coincide con lo que sucede y ademas es totalmente consistente con tu
razonamiento y con el mio. Simplemente nunca dije que la estadistica se
agregaba al indice sino que podia usar el indice como "cover index"
haciendo
un INDEX SCAN sobre el mismo.

Simplemente creo que me mal-interpretaste:

La pregunta original fue:
Por tanto en nuestro ejemplo solo sacarian provecho del indice las
consultas
SELECT ... WHERE ID = x, o WHERE ID = X AND NAME = y o WHERE ID = x AND
NAME
= y AND ADRESS = Z

En tu correo donde te autocorregias expresaste
y por lo tanto se debera hacer un scan de la tabla o el indice clustered
en
caso de este existir.

Lo cual a mi criterio no es correcto ya que no es lo que sucede Esto lo
exprese en mi correo y queria que se hiciera notar ya que no se si MySql
lo
puede aprovechar de la misma manera que SQL Server

Lo que exprese fue:
Alejandro, si la condicion sobre esa columna (c3 = ?) es muy convergente,
supongamos en extremo 1 registro, y si la cantidad de paginas de la tabla
es
grande en comparacion al indice, va a hacer un index scan y luego el
lookup
ya que eso es menos costoso que el scan de la table. Si la cantidad de
registros crece, va a llegar un punto que el costo que produce la
estructura
de los indices y la aleatorizacion de accesos del nonclustered index que
va
a preferir un acceso mediante un table scan.

Nunca exprese que haria un INDEX SEEK para obtener 1 registro sino que
implicitamente asumi que el SQL Server sabe que hay un solo registro.
Aqui
omiti expresar lo de las estadisticas generadas automaticamente asi como
que
me estaba refiriendo a un nonclustered index..

Tu me respondiste
Eso lo sabes tu, pero SQL Server no tiene idea de cuantos registros
cumplen
esa condicion en ese indice puesto que no hay estadisticas para saberlo y
no
va a tomar el riesgo de scanear el indice para luego hacer key lookup

Por eso envie el ejemplo que no coincide con esta frase.
Luego si exprese lo de las estadisticas en mi correo del ejemplo y tu lo
reflejas en tu ultimo correo.

Por lo tanto
IMPORTANTE
***********************************************************************
La respuesta exacta es NO, otras consultas
tambien pueden sacar provecho del indice
aun sin usar la regla de la izquierda.
***********************************************************************

Creo que coincidimos luego de agregar los detalles que faltaban en las
frases.
Espero que les sirva a quienes lo leen ya que creo es bastante rico como
ejemplo..



Saludos


Ing. Jose Mariano Alvarez
SQLTotal Consulting

(Cambia los ceros por O y saca lo que sobra)

Este mensaje se proporciona tal como es, SIN GARANTIAS de ninguna clase.
Por
favor tratar de indicar la versión de SQL y Service Pack. La inclusión de
(CREATE, INSERTS, etc.) para poder reproducir el problema también ayuda.










"Alejandro Mesa" wrote in
message
news:
> Jose Mariano Alvarez,
>
> Creo que tienes una confución aqui, o quizas sea yo quien la tenga, asi
> que
> vamos a tratar de averiguar como el optimizador determino que solo una
> fila
> macha esa expresion.
>
> Logicamente queel optimizador no saco esta conclusión de las
> estadisticas
> normales de ese indice, pues como ya comente anteriormente, tenemos
> estadiscas sobre la distribucion de valores de la columna lider, en
> este
> caso
> A, y tenemos valores de densidad para la combinacion de columnas de el
> indice, combinacion de izquierda a derecha (A), (A, B), (A, B, C).
>
> DBCC SHOW_STATISTICS ('dbo.POC_CoverIndex', 'PK_POC_CoverIndex');
> GO
>
> Entonces de donde saco el optimizador el valor estimado de el numero de
> filas que cumplen la expresion?
>
> Bueno, si la base de datos tiene prendida la opción
> "AUTO_CREATE_STATISTICS", la cual por lo general debe estar prendida,
> entonces al analizar la consulta, este crea una estadistica para la
> columna
> C, pues no existe un indice que nos pueda proveer estadisticas sobre
> esta
> columna por si sola. Al ver que solo una fila macha esta expresion,
> entonces
> decide scanear el indice nonclustered, que es mucho mas estrecho que la
> tabla, pues solo contiene informacion sobre A, B, C y luego hace un
> lookup
> en
> la tabla para traer el valor de la columna [descrip]. Este plan es
> mucho
> menos costoso que leer toda la tabla para encontrar la fila que macha
> con
> esa
> expresion, porque este puede estar al final de la tabla.
>
> Como podemos probar lo dicho?
>
> 1 - Apagamos la opcion AUTO_CREATE_STATISTICS en la db donde se hace la
> prueba. Esto antes de ejecutar ela sentencia select.
>
> ALTER DATABASE prueba
> SET AUTO_CREATE_STATISTICS OFF;
> GO
>
> 2 - Para ser justo, actualizamos las estadisticas de el indice despues
> de
> cargar la tabla.
>
> UPDATE STATISTICS dbo.POC_CoverIndex WITH FULLSCAN;
> GO
>
> 3 - Ejecuta la senetencia select cuantas veces sea necesario, hasta que
> estemos convencidos de lo que vemos, que es el scan de la tabla, pues
> no
> tenemos estadisticas para determinar las filas que machan esa
> expresion.
>
> 4 - Prende la opcion, o en su lugar crea la estadistica a mano.
>
>
> ALTER DATABASE prueba
> SET AUTO_CREATE_STATISTICS ON;
> GO
>
>
> CREATE STATISTICS POC_CoverIndex_C
> ON dbo.POC_CoverIndex(C) WITH FULLSCAN;
> GO
>
> 5 - Limpia el cache de procedimientos por si acaso.
>
> DBCC freeproccache;
> GO
>
> Fijate que tu mismo comentas sobre la estadistica generada
> automaticamente
> sobre la columna C, en tu codigo de ejemplo. Pero eso no quiere decir
> que
> el
> optimizador puso esa estadistica en el indice, sino que creo una nueva
> para
> poder estimar expresiones sobre esa columna y la crea justo por eso,
> porque
> no tenia de donde sacar numero alguno para estimar la cardinalidad de
> la
> expresion.
>
> Si miramos las estadisticas almacenadas en esta nueva estadistica que
> se
> creo (valga aqui la redondancia):
>
> DBCC SHOW_STATISTICS ('dbo.POC_CoverIndex', 'POC_CoverIndex_C');
> GO
>
> Vemos que la segunda fila en el histograma, dice que hay 9,997 filas en
> el
> rango > 1 y <= 9999, que una fila tiene el valor de la columna C = 9999
> y
> que
> 9997 de el resto de los valores son unicos. Por lo que podemos estimar
> que
> solo una fila cumple la expresion C = 500.
>
>
> Vuelvo a repetir, si el indice que tenemos es (A, B, C), en este caso
> nonclustered, y ademas no tenemos indice clustered, y la expresion en
> el
> predicado es:
>
> ...
> where B = ?
>
> ó
>
> ...
> where C = ?
> entonces SQL Server no
>
> entonces el optimizador no tiene de donde estimar el numero de filas
> que
> pueden machar esa expresion. Es por eso que es importante tener
> prendida
> la
> opcion AUTO_CREATE_STATISTICS para que nuevas estadisticas se generen
> cuando
> estas hagan falta. Tambien es importante tener prendida la opcion
> AUTO_UPDATE_STATISTICS para que estas estadisticas se actualizen a
> medida
> que
> insertamos nuevas filas o actualizamos o borramos filas existentes.
>
>
>
> AMB
>
>
>
> "Jose Mariano Alvarez" wrote:
>
>> Va el ejemplo de lo que dije.
>> Lo probe en 2000. 2005 y 2008
>> Espero sirva
>>
>>
>>
>>
>> use prueba
>> go
>>
>>
>>
>> SET NOCOUNT ON
>> GO
>>
>>
>> SET STATISTICS PROFILE OFF
>> go
>>
>>
>>
>> CREATE TABLE dbo.POC_CoverIndex(
>> A smallint NOT NULL,
>> B smallint NOT NULL,
>> C int NOT NULL,
>> descrip char(255) NOT NULL
>> )
>> GO
>> ALTER TABLE dbo.POC_CoverIndex
>> ADD CONSTRAINT PK_POC_CoverIndex PRIMARY KEY NONCLUSTERED (
>> A,B,C
>> )
>> GO
>>
>>
>>
>> declare @I int
>> set @i= 10000
>>
>> While @i > 0
>> begin
>> insert into dbo.POC_CoverIndex
>> values(@i/10000,@i%1000,@i,convert(char(255),@i))
>> set @i = @i -1
>> end
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> if substring(cast(serverproperty('ProductVersion') as
>> varchar(40)),1,1) >> >> '8'
>> select * from sysindexes where id = OBJECT_ID ( 'dbo.POC_CoverIndex' )
>> else
>> select * from sys.indexes where object_id = OBJECT_ID (
>> 'dbo.POC_CoverIndex' )
>>
>>
>>
>> if substring(cast(serverproperty('ProductVersion') as
>> varchar(40)),1,1) >> >> '8' --
>> SQL Server 2000
>> select * from sysindexes where id = OBJECT_ID ( 'dbo.POC_CoverIndex' )
>> and
>> name like '_WA_Sys%'
>> else
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida