En este tema voy a comentar como podemos verificar que se está usando el índice de una forma correcta en una consulta, ya que no solo por que aparezca el índice en el plan de ejecución de la consulta ha de ser correcto.
Por dar una primera pincelada, si nosotros encontramos en un plan de ejecución, donde un índice se esta usando como Index Scan, muy probablemente no se este usando de la forma adecuada, ya que Index Scan para obtener su resultado ha de pasar por todas los campos del índice. Mientras que si encontramos un Index Seek, forma normal de utilización de un índice, solo se accede para obtener el resultado a los campos selectivos por la consulta del índice.
Es aconsejable para el buen entendimiento de este “Tema:VII” que se lea o repase los enlaces: Query Optimizer. Parameter Sniffing. SQL Server. Tema: I y el enlace: Query Optimizer. Cardinality Estimation Error. SQL Server. Tema: II, y sus temas posteriors.
Normalmente, partiendo de escenarios con índices y estadísticas actualizadas, cuando usamos consultas donde filtramos por un valor específico como por ejemplo: Select ProductID, SalesOrderID, salesOrderDetailID form sales. salesOrderDetail where ProductID =771 Os voy a mostrar un ejemplo en un plan de ejecución donde se ve la forma correcta de cómo ha de usarse un índice,. Veremos que usa el operador: Index Seek, y verificamos que usa predicados de búsqueda: Seek Predicates:
![](http://www.fullblog.com.ar/blogs/microsoftsqlsecret/1304812842591178.jpg)
Se suelen dar en casos donde utilizamos funciones o diferentes expresiones para filtrar en las consultas, como por ejemplo: Select ProductID, SalesOrderID, salesOrderDetailID form sales. salesOrderDetail where ABS(ProductID) =771 quizás SQL Server, no va a utiliza los índices deforma correcta. En el ejemplo que os muestro en el plan de ejecución de la consulta, vemos que usa Index Scan, donde hace un scan del indice que por lo menos es mejor hacer un scan de la tabla (Table Scan). Vemos que no tenemos un Seek Predicates pero si un Predicate -> esto no es bueno, ya que hace un sacan de todo el índice para buscar los valores específicos de ProductID.
![](http://www.fullblog.com.ar/blogs/microsoftsqlsecret/1304812812905177.jpg)
Obviamente, podemos estar en escenarios con índices de más de una columna, y con varios predicados, como es el caso en del ejemplo: Select ProductID, SalesOrderID, salesOrderDetailID form sales. salesOrderDetail where ProductID =771 AND SalesOrderID=45233 para este caso, el resultado es muy bueno por que usa un Index Seek y nos hemos de fijar que en el Seek Predicates hace la búsqueda por las dos columnas ProducID y SalesOrderID:
![](http://www.fullblog.com.ar/blogs/microsoftsqlsecret/1304812701441724.jpg)
Como ultimo caso, voy a mostrar una mezcla de los casos anteriores: Select ProductID, SalesOrderID, salesOrderDetailID form sales. salesOrderDetail where ProductID =771 AND ABS(SalesOrderID)=45233 en estos casos puede ser mas difícil de encontrar un problema aunque veamos que usa un Index Seek y nos parezca que todo esta perfecto, realmente no lo esta, por que en el Seek Predicates solo busca por ProductID, y no por la función ABS(salesOrderID), donde vemos que hace su busqueda en el Predicate: (El índice hace dos operaciones, primero busca el ProductID, haciendo uso del Index Seek, y segundo busca por SalesOrderID haciendo un Scan de la columna en índice…)
![](http://www.fullblog.com.ar/blogs/microsoftsqlsecret/1304812642895437.jpg)
Se aconseja leer: Actualización de estadísticas síncronas o asíncronas mejoran la respuesta del optimizador de consultas. SQL Server
Fuentes:
Microsoft, MSDN, Benjamin Nevares
Apunte y recopilación por Norman M. Pardell
Puedes consultarme, si deseas cualquier aclaración, pregunta o sugerencia en: Contacto, contestaré tan pronto como me sea posible.