¿Cuándo es mejor crear ESTADÍSTICAS en lugar de crear un Índice?

38

He encontrado mucha información sobre qué STATISTICS son: cómo se mantienen, cómo se pueden crear de forma manual o automática a partir de consultas o índices, y así sucesivamente. Pero no he podido encontrar ninguna orientación o información de "mejores prácticas" sobre cuándopara crearlos: qué situaciones se benefician más de un objeto ESTADÍSTICAS creado manualmente que de un índice. He visto estadísticas filtradas creadas manualmente que ayudan a las consultas en tablas particionadas (porque las estadísticas creadas para los índices cubren toda la tabla y no son por partición, ¡genial!), Pero seguramente debe haber otros escenarios que se beneficiarían de un objeto de estadísticas mientras no necesita el detalle de un índice, ni vale la pena el costo de mantener el índice o aumentar las posibilidades de bloqueo / bloqueo.

@JonathanFite, en un comentario, mencionó una distinción entre índices y estadísticas:

Los índices ayudarán a SQL a encontrar los datos más rápido al crear búsquedas que se ordenan de manera diferente a la tabla misma. Las estadísticas ayudan a SQL a determinar cuánta memoria / esfuerzo se necesitará para satisfacer la consulta.

Esa es una gran información, principalmente porque me ayuda a aclarar mi pregunta:

¿Cómo saber esto (o cualquier otra información técnica sobre la que S y cómo s relacionados con los comportamientos y naturaleza de STATISTICS) ayudar a determinar cuándo elegir CREATE STATISTICSmás CREATE INDEX, sobre todo cuando se crea un índice relacionado creará el STATISTICSobjeto? ¿Qué escenario sería mejor al tener solo la información ESTADÍSTICA y no tener el Índice?

Sería súper útil, si es posible, tener un ejemplo funcional de un escenario en el que el STATISTICSobjeto se ajuste mejor que un INDEX.


Puesto que soy un aprendiz visual / pensador, pensé que podría ayudar a ver las diferencias entre STATISTICSy INDEXES, de lado a lado, como un posible medio para ayudar a determinar cuándo STATISTICSson la mejor opción.

Thingy           PROs                             CONs
-------          ----------                       -------------------
INDEX            * Can help sorts.                * Takes up space.
                 * Contains data (can             * Needs to be maintained (extra I/O).
                   "cover" a query).              * More chances for blocking / dead-locks.

STATISTICS       * Takes up very little space.    * Cannot help sorts.
                 * Lighter maintenance / won't    * Cannot "cover" queries.
                   slow down DML operations.
                 * Does not increase chances
                   of blocking / dead-locks.

Los siguientes son algunos recursos que encontré mientras buscaba esto, uno que incluso hace esta misma pregunta, pero no fue respondida:

Índice de SQL Server vs Estadística

Preguntas sobre estadísticas de SQL Server que fuimos demasiado tímidos para hacer

Estadística. ¿Son posibles los histogramas de varias columnas?

** Para ser claros, no tengo una respuesta para esto y en realidad estoy buscando recibir comentarios de algunas personas para proporcionar lo que parece ser una información extrañamente extraña aquí en las páginas web.

Solomon Rutzky
fuente
1
Los índices ayudarán a SQL a encontrar los datos más rápido al crear búsquedas que se ordenan de manera diferente a la tabla misma. Las estadísticas ayudan a SQL a determinar cuánta memoria / esfuerzo se necesitará para satisfacer la consulta.
Jonathan Fite
@ JonathanFite Gracias por ese comentario. Lo he incorporado a mi pregunta :).
Solomon Rutzky
Siguiendo el comentario de @ JonathanFite, parece que las estadísticas son mejores para aumentar el rendimiento en sistemas / tablas / patrones de consulta ad hoc, mientras que los índices son mejores para patrones de consulta predecibles. Me refiero a esto como más una pregunta que una declaración.
Dave

Respuestas:

19

Tu pregunta gira en torno a: ¿cuándo es bueno crear estadísticas versus crear índices (que crean estadísticas)?

De mis notas internas del servidor sql (clase SQLSkills- IE1 e IE2) y el libro interno de SQL Server , a continuación es mi comprensión limitada :

Las estadísticas de SQL Server no son más que objetos del sistema que contienen información vital sobre los valores de clave de índice y los valores de columna regulares.

SQL Server utiliza un modelo basado en costos para elegir un plan de ejecución "suficientemente bueno" lo más rápido posible. La estimación de la cardanilidad (estimación del número de filas que se procesarán en cada paso de la ejecución de la consulta) es el factor más importante en la optimización de la consulta, que afecta la estrategia de unión, el requisito de concesión de memoria, la selección de subprocesos de los trabajadores y la elección de índices al acceder a los datos .

SQL Server no usará índices no agrupados cuando estima que un gran no. Se requerirán operaciones de bucle KEY o RID, por lo que mantiene estadísticas sobre índices (y en columnas) que ayudarán en tales estimaciones.

Hay 2 cosas importantes sobre las estadísticas:

  1. El histograma almacena información sobre la distribución de datos SOLAMENTE para la columna de estadísticas (índice) más a la izquierda. También almacena información sobre la densidad de columnas múltiples de los valores clave. En esencia, el histograma almacena la distribución de datos solo para la columna de estadísticas más a la izquierda.

  2. SQL Server retendrá como máximo 200 pasos en el histograma, independientemente del tamaño de la tabla. Los intervalos cubiertos por cada paso del histograma aumentan a medida que crece la tabla, lo que conduce a estadísticas "menos precisas" para tablas grandes.

    Recuerde que la selectividad del índice es una métrica que es inversamente proporcional a la densidad, es decir, cuantos más valores únicos tenga una columna, mayor será su selectividad.

Cuando las consultas particulares no se ejecutan con mucha frecuencia, puede seleccionar crear estadísticas a nivel de columna en lugar de un índice. Las estadísticas a nivel de columna ayudan a Query Optimizer a encontrar mejores planes de ejecución, a pesar de que esos planes de ejecución son subóptimos debido a los escaneos de índice involucrados. Al mismo tiempo, las estadísticas no agregan una sobrecarga durante las operaciones de modificación de datos y ayudan a evitar el mantenimiento del índice. Este enfoque solo funciona para consultas raramente ejecutadas.

Referir:

Nota: Alguien como Paul White o Aaron Bertrand puede intervenir para darle más color a su buena pregunta .

Kin Shah
fuente
"SQL Server no usará índices no agrupados cuando estima que se requerirá un gran número de operaciones de bucle KEY o RID" Entonces, ¿puede el QO usar el objeto de estadísticas basado en un índice independientemente del índice? Es decir, si el índice no es óptimo, pero la columna principal está en la consulta, las estadísticas siguen siendo relevantes. Entonces, ¿serían utilizados? ¿O esta información implica que podría haber casos en los que un índice probablemente no se usaría, pero dado que las estadísticas aún tienen valor, entonces no hay una razón real para crear el índice, solo haga las estadísticas?
Solomon Rutzky
8

Diría que necesita un índice cuando necesita poder limitar la cantidad de datos / obtener los datos correctos rápidamente en función de los campos.

Necesita estadísticas cuando necesita que el optimizador comprenda la naturaleza de los datos para poder realizar las operaciones de la mejor manera posible.

Lo que he descubierto es que las estadísticas filtradas ayudan cuando hay sesgos en los datos que afectan en gran medida al plan, por ejemplo, en el desbordamiento de la pila, pocos usuarios tienen una gran cantidad de publicaciones, por lo que usar solo publicaciones promedio por usuario no es realmente la mejor estimación. Por lo tanto, puede crear estadísticas filtradas en userId en función del nombre de usuario y luego SQL Server debe saber que cuando este nombre de usuario está en la consulta, esta es la identificación de usuario que obtendrá, y debería ser capaz de descubrir que el El campo indexado en la tabla de publicaciones tendrá una gran cantidad de filas con esa identificación porque el histograma existe allí. Con promedios, no es posible hacer eso.

James Z
fuente
1
Hola, y gracias por responder. Entonces, ¿cuándo necesitaría / desearía que el optimizador comprenda mejor la naturaleza de los datos y, sin embargo, no limite esos datos o desee obtenerlos más rápido, o necesite que "cubra" la consulta? Lo mismo para su ejemplo de índice filtrado. Entiendo lo que está diciendo en términos de desglosar los casos límite de los promedios, pero ¿por qué las estadísticas filtradas serían mejores que un índice filtrado en los mismos campos? Esta es la distinción a la que estoy tratando de llegar.
Solomon Rutzky
Como en el ejemplo, no puede crear un índice filtrado en el nombre del usuario en la tabla de publicaciones porque no existe allí. Puede crearlo en función de la identificación del usuario, pero eso no está en la cláusula where.
James Z
Pero no UserIDestaría en la condición de UNIRSE, incluso si no estuviera en el WHERE? ¿Y eso no sería lo suficientemente bueno como para recoger un índice filtrado?
Solomon Rutzky
@srutzky Quizás sea más probable en las versiones más actuales, pero en general no confiaría en eso ... en la mayoría de los casos, los predicados tienen que coincidir exactamente. Olvidé si arreglaron esto, pero en un punto WHERE BitColumn = 0no se seleccionaría un índice filtrado para una consulta simple WHERE BitColumn <> 1. (Y para ser claros, la columna de bits no era anulable). Creo que hubo casos similares como IntColumn > 10no coincidir IntColumn >= 11.
Aaron Bertrand
Los índices filtrados no se pueden usar si existe la posibilidad de que la próxima vez que alguien use los planes, el índice filtrado ya no sea adecuado. No puedo pensar en ninguna combinación que pueda usar un índice filtrado. Incluso las variables no se pueden usar porque la próxima vez el valor podría ser algo no adecuado.
James Z
4

70-461 Libro de entrenamiento de Itzik Ben-Gan

Solo hay algunas razones posibles para crear estadísticas manualmente. Un ejemplo es cuando un predicado de consulta contiene varias columnas que tienen relaciones entre columnas; Las estadísticas en las múltiples columnas pueden ayudar a mejorar el plan de consulta. Las estadísticas en varias columnas contienen densidades de columnas cruzadas que no están disponibles en las estadísticas de una sola columna. Sin embargo, si las columnas ya están en el mismo índice, el objeto de estadísticas de varias columnas ya existe, por lo que no debe crear uno adicional manualmente.

Kentaro
fuente
Gracias por publicar esto. Esto responde parte de mi pregunta pero aún deja abierta la pregunta de: Si necesito las estadísticas de varias columnas, ¿por qué crearía solo las ESTADÍSTICAS en lugar del Índice, que incluiría las ESTADÍSTICAS más información adicional que podría ayudar aún más a la consulta ( ies)?
Solomon Rutzky
1
Creo que la explicación de Kin explicaría aún más lo que buscas. ¿Quizás un montón que se inserta con frecuencia, pero que rara vez se consulta?
Kentaro