sql >> Base de Datos >  >> RDS >> Sqlserver

Internos de SQL Server:Operadores problemáticos Pt. Yo – Escaneo

SQL Server existe desde hace más de 30 años y yo he estado trabajando con SQL Server durante casi el mismo tiempo. Kalen cubre los análisis en la primera parte de SQL Server Internals:Operadores problemáticos.

He visto muchos cambios a lo largo de los años (¡y décadas!) y versiones de este increíble producto. En estas publicaciones, compartiré con ustedes cómo veo algunas de las características o aspectos de SQL Server, a veces junto con un poco de perspectiva histórica.

Ajustar sus consultas de SQL Server es una de las mejores cosas que puede hacer para mejorar el rendimiento y la optimización de los diagnósticos de SQL Server. ¡Pero el tuning es un tema enorme! Saber exactamente cómo sintonizar de la mejor manera posible requiere no solo un conocimiento profundo de sus datos y su carga de trabajo, sino también el conocimiento de cómo SQL Server realmente toma sus decisiones de ejecución del plan. Entonces, ¿qué puede hacer si no es un experto en SQL Server Internals? Una cosa que puede hacer es confiar en personas que son expertas, así como en herramientas escritas por expertos. Herramientas como Quest Spotlight Cloud Tuning Pack pueden brindarle excelentes sugerencias para comenzar el camino hacia un mejor rendimiento de las consultas. Por supuesto, ninguna herramienta externa conoce sus datos y todos los detalles de todas sus cargas de trabajo, por lo que siempre se recomienda realizar pruebas exhaustivas de cualquier sugerencia que decida implementar.

En estas publicaciones sobre operadores problemáticos, asumiré que tiene algún conocimiento básico de las estructuras de índice de SQL Server. Aquí hay alguna información que será útil:

  • Una tabla sin un índice agrupado se denomina montón y no tiene ningún orden. No hay primera fila ni última fila. Un montón es solo un montón de filas sin ningún orden en particular.
  • El nivel hoja de un índice agrupado es la tabla misma. (No es una copia de la tabla, ES la tabla). Las filas del índice están ordenadas lógicamente por cualquier columna que se definió como la clave del índice agrupado.
  • El nivel hoja de un índice no agrupado contiene una fila de índice para cada fila de la tabla. Las filas contienen las columnas de clave no agrupadas y están ordenadas lógicamente en el orden en que se especifican las claves. Además de las columnas clave, las filas del índice no agrupado contienen un "marcador" que apunta a la fila a la que se hace referencia en la tabla. El marcador puede tener una de dos formas:
    1. Si la tabla tiene un índice agrupado, el marcador es la clave del índice agrupado. (Si la clave de índice agrupado es parte de la clave de índice no agrupado, no se duplicará).
    2. Si la tabla es un montón, el marcador es un Id. de fila o RID, que especifica la ubicación física de la fila. La ubicación generalmente se especifica como FileNum:PageNum:RowNum .

Las propias herramientas de SQL Server brindan múltiples formas de ver el plan de ejecución de consultas que el optimizador decidió usar para una consulta en particular. Con la adición de Quest Spotlight Tuning Pack, puede obtener aún más información sobre sus planes.

El siguiente código crea copias de dos tablas en AdventureWorks base de datos (estoy usando AdventureWorks2016 , pero podría usar otra versión).

USE AdventureWorks2016;

GO

DROP TABLE IF EXISTS SalesHeader;

GO

SELECT *

INTO SalesHeader

FROM Sales.SalesOrderHeader;

GO

DROP TABLE IF EXISTS SalesDetail;

GO

SELECT * INTO SalesDetail

FROM Sales.SalesOrderDetail;

GO

Ahora ejecute una consulta que una las dos tablas, después de activar "Incluir plan de ejecución real"

SELECT h.SalesOrderID, OrderDate, ProductID, UnitPrice, OrderQty

FROM SalesHeader h JOIN SalesDetail d

ON h.SalesOrderID = d.SalesOrderID

WHERE SalesOrderDetailID < 100;

GO

Quest Spotlight Tuning Pack informará un problema con la consulta, por lo que puede hacer clic en "Ver análisis" y elegir la opción "Plan de ejecución". Debería ver lo siguiente:

Comprensión de los escaneos de tablas

Primero, quiero aventurarme y decir que no hay un operador de plan que siempre sea malo. ¿Por qué el optimizador lo agregaría a su plan de consulta si fuera malo? Puede indicar que hay margen de mejora en sus datos o estructuras de índice, pero en sí mismo no es malo.

En el ejemplo anterior, el Tuning Pack parece estar destacando los escaneos de la tabla, lo que indica que pueden ser problemáticos. Pero no siempre es cierto que los escaneos de tablas sean problemáticos. Una situación mucho peor sería utilizar una búsqueda de índice no agrupado para una consulta que acceda a todas las filas de la tabla. Para esta consulta en particular, estaría de acuerdo en que el escaneo podría no ser bueno porque solo nos interesan unas pocas filas en SalesDetail tabla (99 de 121 317 filas, o menos de una décima parte de un porcentaje).

Entonces, podríamos ver las sugerencias en el panel Análisis para crear índices. La sugerencia para SalesDetail la tabla es construir un índice no agrupado en el SalesOrderID columna (la columna de la cláusula JOIN) e INCLUDE todas las demás columnas de la tabla que devuelve la consulta. La sugerencia para el SalesHeader la tabla es un índice no agrupado en SalesOrderDetailId columna, que es la columna en la cláusula WHERE, e INCLUYE la OrderDate columna, que es la única otra columna devuelta de esta tabla.

¿Qué pasaría si nuestra consulta fuera ligeramente diferente? ¿Qué pasaría si hubiera ejecutado esta consulta usando SELECT * en lugar de una lista de columnas específica? Si lo prueba y observa las recomendaciones, sugiere usar INCLUDE para cada columna de la tabla que no sea la columna de clave única. Aunque dicho índice podría hacer que esta consulta en particular se ejecute un poco más rápido, podría terminar ralentizando otras consultas, en particular, las consultas de ACTUALIZACIÓN. Básicamente, este índice es solo una copia de la tabla, porque el nivel de hoja del índice contendrá todas las columnas de la tabla. Si ve recomendaciones como esta, sugiriendo un índice que incluya todas las columnas de la tabla, definitivamente recomiendo dar un paso atrás y no crearlo a ciegas.

El ajuste de consultas para los diagnósticos de su servidor SQL implica no solo administrar índices, sino también administrar las propias consultas. Para esta consulta en particular, sería mejor que reescribiéramos la consulta para NO usar SELECT * para devolver cada fila de la tabla. Devolver solo un pequeño subconjunto de las columnas podría ser suficiente, y luego sería suficiente un índice mucho más estrecho, como en el primer ejemplo.

¿Alguno de estos índices sería realmente un buen índice para crear? El índice más estrecho será más pequeño en general y se verá menos afectado por las actualizaciones de los datos. Un índice en todas las columnas es como una segunda copia de la tabla, ordenada en un orden diferente al de la tabla misma. Hay situaciones en las que tener una "segunda copia" de la tabla en un orden diferente puede ser útil, pero habrá muchos gastos generales para las operaciones de modificación de datos. La única forma de saberlo con certeza es probar las recomendaciones en un sistema de prueba con una carga de trabajo representativa. Solo tú conoces tus datos y tus consultas, ¡así que pruébalo y verás!

Comprensión de los escaneos de índice

Como mencioné anteriormente, los escaneos de tablas no siempre son algo malo. Pero, ¿qué pasa con los escaneos de índice? Debido a que un nivel de hoja de índice agrupado es la tabla misma, ¡un escaneo de índice agrupado es lo mismo que un escaneo de tabla! si un escaneo de tabla es malo, un escaneo de índice agrupado es igual de malo. Pero no siempre es malo. Una vez más, debe probarlo en su sistema.

Las recomendaciones del motor de SQL Server que muestra Quest Spotlight Tuning Pack nunca sugieren un índice agrupado. puede sugerir un no agrupado que incluye todas las columnas de la tabla (como se mencionó anteriormente), que es solo un duplicado de la tabla. Averiguar la mejor columna o columnas para su índice agrupado es un gran tema en sí mismo, por lo que no entraré en eso aquí.

¿Qué es una búsqueda? Una operación de búsqueda en un plan significa que SQL Server está utilizando los datos ordenados en el árbol de índices para encontrar una fila, un conjunto de filas o el punto de inicio o finalización en un rango de filas. En general, usar una búsqueda de índice no agrupado es una operación perfectamente razonable si solo devuelve un porcentaje muy pequeño de filas de una tabla. Pero una búsqueda no es una buena opción para una consulta que devuelve MUCHAS filas de una tabla. ¿Cuánto es LOTES? No hay una respuesta simple, pero si su consulta devuelve más de un pequeño porcentaje de las filas, debe asegurarse de probar las sugerencias de índice a fondo. A veces, un escaneo de tabla o un escaneo de índice agrupado es mejor que una búsqueda de índice. (Para ver un ejemplo de este tipo, consulte la publicación de mi blog aquí).

Herramientas como Paquete de ajuste de Quest Spotlight puede brindarle excelentes sugerencias para comenzar su viaje de ajuste con el diagnóstico del servidor SQL, pero cuanto más sepa sobre cómo funcionan los índices de SQL Server y el optimizador de SQL Server, mejor podrá evaluar esas sugerencias para sus consultas y su datos, y posiblemente incluso proponga sugerencias propias.

En las siguientes publicaciones de esta serie, le informaré sobre otros operadores problemáticos que podrían aparecer en sus planes de consulta, ¡así que vuelva pronto!