Tengo una base de datos SQL Server donde las consultas son bastante lentas y hay muchos bloqueos y bloqueos.
Cuando miro los índices DMV faltantes y los planes de consulta, no hay ninguna sugerencia.
¿Porqué es eso?
Tengo una base de datos SQL Server donde las consultas son bastante lentas y hay muchos bloqueos y bloqueos.
Cuando miro los índices DMV faltantes y los planes de consulta, no hay ninguna sugerencia.
¿Porqué es eso?
Respuestas:
Analizaremos algunas de las razones con más detalle y también hablaremos sobre algunas de las limitaciones generales de la función.
Primero, de: Limitaciones de la característica de índices faltantes :
- No especifica un orden para las columnas que se utilizarán en un índice.
Como se señaló en estas preguntas y respuestas: ¿Cómo determina SQL Server el orden de las columnas clave en las solicitudes de índice que faltan? , el orden de las columnas en la definición del índice está dictado por el predicado Igualdad vs Desigualdad, y luego la posición ordinal de la columna en la tabla.
No hay conjeturas sobre la selectividad, y puede haber un mejor pedido disponible. Es tu trabajo resolver eso.
Índices especiales
Las solicitudes de índice que faltan tampoco cubren índices 'especiales', como:
Las columnas de clave de índice que faltan se generan a partir de columnas utilizadas para filtrar resultados, como las de:
Las columnas incluidas en el índice perdido se generan a partir de columnas requeridas por la consulta, como las de:
Aunque con bastante frecuencia, las columnas por las que está ordenando o agrupando pueden ser beneficiosas como columnas clave. Esto se remonta a una de las limitaciones:
- No está destinado a ajustar una configuración de indexación.
Por ejemplo, esta consulta no registrará una solicitud de índice faltante, aunque agregar un índice en LastAccessDate evitaría la necesidad de ordenar (y derramar al disco).
SELECT TOP (1000) u.DisplayName
FROM dbo.Users AS u
ORDER BY u.LastAccessDate DESC;
Tampoco esta consulta de agrupación en Ubicación.
SELECT TOP (20000) u.Location
FROM dbo.Users AS u
GROUP BY u.Location
Bueno, sí, pero es mejor que nada. Piense en las solicitudes de índice faltantes como un bebé que llora. Sabes que hay un problema, pero de ti depende como adulto descubrir cuál es ese problema.
Relájate, bucko. Estamos llegando a eso.
Si habilita TF 2330 , las solicitudes de índice que faltan no se registrarán. Para saber si tiene esto habilitado, ejecute esto:
DBCC TRACESTATUS;
La reconstrucción de índices borrará las solicitudes de índice que faltan. Por lo tanto, antes de irse Hi-Ho-Silver-Away reconstruyendo cada índice en el segundo en que se cuela una pizca de fragmentación, piense en la información que está limpiando cada vez que lo hace.
Es posible que también desee pensar en Por qué la desfragmentación de sus índices no ayuda , de todos modos. A menos que esté usando Columnstore .
Agregar, eliminar o deshabilitar un índice borrará todas las solicitudes de índice que faltan para esa tabla. Si está trabajando en varios cambios de índice en la misma tabla, asegúrese de escribirlos todos antes de realizarlos.
Si un plan es lo suficientemente simple, y la opción de acceso al índice es lo suficientemente obvia, y el costo es lo suficientemente bajo, obtendrá un plan trivial.
Esto significa efectivamente que el optimizador no tomó decisiones basadas en costos.
Vía Paul White :
Los detalles de qué tipos de consulta pueden beneficiarse del Plan Trivial cambian con frecuencia, pero cosas como uniones, subconsultas y predicados de desigualdad generalmente impiden esta optimización.
Cuando un plan es trivial, no se exploran fases de optimización adicionales y no se solicitan índices faltantes .
Vea la diferencia entre estas consultas y sus planes :
SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2;
SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2
AND 1 = (SELECT 1);
El primer plan es trivial y no se muestra ninguna solicitud. Puede haber casos en que los errores eviten que aparezcan índices faltantes en los planes de consulta; sin embargo, generalmente se registran de manera más confiable en los DMV de índice que faltan.
Las predicciones en las que el optimizador no podría usar un índice de manera eficiente incluso con un índice pueden evitar que se registren.
Las cosas que generalmente no son SARGable son:
SELECT *
FROM dbo.Users AS u
WHERE ISNULL(u.Age, 1000) > 1000;
SELECT *
FROM dbo.Users AS u
WHERE DATEDIFF(DAY, u.CreationDate, u.LastAccessDate) > 5000
SELECT *
FROM dbo.Users AS u
WHERE u.UpVotes + u.DownVotes > 10000000
DECLARE @ThisWillHappenWithStoredProcedureParametersToo NVARCHAR(40) = N'Eggs McLaren'
SELECT *
FROM dbo.Users AS u
WHERE u.DisplayName LIKE @ThisWillHappenWithStoredProcedureParametersToo
OR @ThisWillHappenWithStoredProcedureParametersToo IS NULL;
Ninguna de estas consultas registrará solicitudes de índice que faltan. Para obtener más información sobre estos, consulte los siguientes enlaces:
Toma este índice:
CREATE INDEX ix_whatever ON dbo.Posts(CreationDate, Score) INCLUDE(OwnerUserId);
Se ve bien para esta consulta:
SELECT p.OwnerUserId, p.Score
FROM dbo.Posts AS p
WHERE p.CreationDate >= '20070101'
AND p.CreationDate < '20181231'
AND p.Score >= 25000
AND 1 = (SELECT 1)
ORDER BY p.Score DESC;
El plan es una simple búsqueda ...
Pero debido a que la columna clave principal es para el predicado menos selectivo, terminamos haciendo más trabajo del que deberíamos:
Tabla 'Publicaciones'. Escaneo número 13, lecturas lógicas 136890
Si cambiamos el orden de las columnas de la clave de índice, hacemos mucho menos trabajo:
CREATE INDEX ix_whatever ON dbo.Posts(Score, CreationDate) INCLUDE(OwnerUserId);
Y significativamente menos lecturas:
Tabla 'Publicaciones'. Escaneo recuento 1, lecturas lógicas 5
En ciertos casos, SQL Server elegirá crear un índice sobre la marcha a través de un carrete de índice. Cuando hay un spool de índice, no habrá una solicitud de índice faltante. Seguramente agregar el índice usted mismo podría ser una buena idea, pero no cuente con que SQL Server lo ayude a resolverlo.