¿Por qué SQL Server no tiene solicitudes de índice faltantes en los DMV o los planes de consulta?


14

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:


17

¡Hay muchas razones por las que no le faltan solicitudes de índice!

Analizaremos algunas de las razones con más detalle y también hablaremos sobre algunas de las limitaciones generales de la función.

Limitaciones generales

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:

  • Agrupados
  • Filtrado
  • Particionado
  • Comprimido
  • XML-ed
  • Ed. Espacial
  • Columnstore-d
  • Vista indexada

¿Qué columnas se consideran?

Las columnas de clave de índice que faltan se generan a partir de columnas utilizadas para filtrar resultados, como las de:

  • Uniones
  • Dónde cláusula

Las columnas incluidas en el índice perdido se generan a partir de columnas requeridas por la consulta, como las de:

  • SELECCIONE
  • AGRUPAR POR
  • ORDENAR POR

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;

NUECES

Tampoco esta consulta de agrupación en Ubicación.

SELECT TOP (20000) u.Location
FROM dbo.Users AS u
GROUP BY u.Location

NUECES

¡Eso no suena muy útil!

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.

Sin embargo, todavía no me has dicho por qué no los tengo ...

Relájate, bucko. Estamos llegando a eso.

Banderas de seguimiento

Si habilita TF 2330 , las solicitudes de índice que faltan no se registrarán. Para saber si tiene esto habilitado, ejecute esto:

DBCC TRACESTATUS;

Reconstrucciones de índice

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 índices

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.

Planes triviales

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);

NUECES

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.

SARGability

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:

  • Columnas envueltas en funciones.
  • Columna + SomeValue = SomePredicate
  • Column + AnotherColumn = SomePredicate
  • Columna = @Variable O @Variable IS NULL

Ejemplos:

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:

Ya tienes un índice aceptable

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 ...

NUECES

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);

NUECES

Y significativamente menos lecturas:

Tabla 'Publicaciones'. Escaneo recuento 1, lecturas lógicas 5

SQL Server está creando índices para usted

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.

NUECES

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.