Tengo la siguiente consulta SQL:
SELECT
Event.ID,
Event.IATA,
Device.Name,
EventType.Description,
Event.Data1,
Event.Data2
Event.PLCTimeStamp,
Event.EventTypeID
FROM
Event
INNER JOIN EventType ON EventType.ID = Event.EventTypeID
INNER JOIN Device ON Device.ID = Event.DeviceID
WHERE
Event.EventTypeID IN (3, 30, 40, 41, 42, 46, 49, 50)
AND Event.PLCTimeStamp BETWEEN '2011-01-28' AND '2011-01-29'
AND Event.IATA LIKE '%0005836217%'
ORDER BY Event.ID;
También tengo un índice en la Event
tabla para la columna TimeStamp
. Tengo entendido que este índice no se usa debido a la IN()
declaración. Entonces, mi pregunta es ¿hay alguna manera de hacer un índice para esta IN()
declaración en particular para acelerar esta consulta?
También intenté agregar Event.EventTypeID IN (2, 5, 7, 8, 9, 14)
como filtro para el índice TimeStamp
, pero al mirar el plan de ejecución no parece estar usando este índice. Cualquier sugerencia o idea sobre esto sería muy apreciada.
A continuación se muestra el plan gráfico:
Y aquí hay un enlace al archivo .sqlplan .
Respuestas:
Tablas dadas de la siguiente forma general:
El siguiente índice es útil:
Para la consulta:
El filtro cumple con el
AND
requisito de la cláusula, la primera clave del índice permite buscar[TimeStamp]
el filtradoEventTypeIDs
y laDeviceID
columna incluye la cobertura del índice (porqueDeviceID
es necesario para la unión a laDevice
tabla).La segunda clave del índice
EventTypeID
no es estrictamente necesaria (también podría ser unaINCLUDEd
columna); Lo he incluido en la clave por los motivos aquí expuestos . En general, aconsejo a las personas que al menosINCLUDE
columnas de unaWHERE
cláusula de índice filtrada .Basado en la consulta actualizada y el plan de ejecución en la pregunta, estoy de acuerdo en que el índice más general sugerido por SSMS es probablemente la mejor opción aquí, a menos que la lista de filtrados
EventTypeIDs
sea estática como Aaron también menciona en su respuesta:Índice sugerido (declararlo único si es apropiado):
Información de cardinalidad del plan de ejecución (sintaxis no documentada, no usar en sistemas de producción):
Consulta actualizada (repetir la
IN
lista para laEventType
tabla ayuda al optimizador en este caso específico):Plan de ejecución estimado:
Es probable que el plan que obtenga sea diferente porque estoy usando estadísticas adivinadas. El punto general es proporcionar al optimizador tanta información como sea posible y proporcionar un método de acceso eficiente (índice) en la
[Event]
tabla de 4 millones de filas .fuente
La mayor parte del costo es el escaneo de índice agrupado, y a menos que esta tabla sea realmente amplia o realmente no necesite todas esas columnas en la salida, creo que SQL Server es la ruta óptima en el escenario actual sin nada más cambiado . Utiliza un escaneo de rango (etiquetado como una búsqueda de CI) para reducir el rango de filas en el que está interesado, pero debido a la salida, aún requerirá una búsqueda o un escaneo de CI incluso con el índice filtrado que creó. está dirigido a este rango, e incluso en ese caso, el escaneo de CI probablemente sea aún más barato (o al menos SQL Server lo estima como tal).
El plan de ejecución le dice que este índice sería útil:
Aunque dependiendo de su sesgo de datos, podría ser mejor al revés, por ejemplo:
Pero probaría ambos para estar seguro de cuál es mejor, si es así: la diferencia entre cualquiera de esos índices y lo que tiene ahora solo puede ser marginal (demasiadas variables para que sepamos) y debe tener en cuenta que un adicional El índice requiere mantenimiento adicional, y esto puede afectar notablemente sus operaciones DML (insertar / actualizar / eliminar). También puede considerar incluir los criterios de filtro en este índice como lo sugiere @SQLKiwi , pero solo si ese es el conjunto de valores EventTypeID que busca con frecuencia. Si ese conjunto cambia con el tiempo, el índice filtrado solo será útil para esta consulta específica.
Con un recuento de filas tan bajo, me pregunto qué tan malo podría ser el rendimiento actualmente. Esta consulta devuelve 3 filas (pero no hay ninguna indicación de cuántas filas rechazó). ¿Cuántas filas hay en la tabla?
fuente
Acabo de descubrir que SQL Server 2008 R2 realmente hizo una sugerencia de índice cuando ejecuté el plan de ejecución. Este índice sugerido hace que la consulta se ejecute aproximadamente un 90% más rápido.
El índice que sugirió fue el siguiente:
fuente