Tengo una consulta que se ejecuta mucho más rápido con select top 100
y mucho más lento sin top 100
. El número de registros devueltos es 0. ¿Podría explicar la diferencia en los planes de consulta o compartir enlaces donde se explica esa diferencia?
La consulta sin top
texto:
SELECT --TOP 100
*
FROM InventTrans
JOIN
InventDim
ON InventDim.DATAAREAID = 'dat' AND
InventDim.INVENTDIMID = InventTrans.INVENTDIMID
WHERE InventTrans.DATAAREAID = 'dat' AND
InventTrans.ITEMID = '027743' AND
InventDim.INVENTLOCATIONID = 'КзРЦ Алмат' AND
InventDim.ECC_BUSINESSUNITID = 'Казахстан';
El plan de consulta para lo anterior (sin top
):
Las estadísticas IO y TIME (sin top
):
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
(0 row(s) affected)
Table 'INVENTDIM'. Scan count 0, logical reads 988297, physical reads 0, read-ahead reads 1, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'INVENTTRANS'. Scan count 1, logical reads 1234560, physical reads 0, read-ahead reads 14299, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 6256 ms, elapsed time = 13348 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Los índices utilizados (sin top
):
1. INVENTTRANS.I_177TRANSIDIDX
4 KEYS:
- DATAAREAID
- INVENTTRANSID
- INVENTDIMID
- RECID
2. INVENTTRANS.I_177ITEMIDX
3 KEYS:
- DATAAREAID
- ITEMID
- DATEPHYSICAL
3. INVENTDIM.I_698DIMIDIDX
2 KEYS:
- DATAAREAID
- INVENTDIMID
La consulta con top
:
SELECT TOP 100
*
FROM InventTrans
JOIN
InventDim
ON InventDim.DATAAREAID = 'dat' AND
InventDim.INVENTDIMID = InventTrans.INVENTDIMID
WHERE InventTrans.DATAAREAID = 'dat' AND
InventTrans.ITEMID = '027743' AND
InventDim.INVENTLOCATIONID = 'КзРЦ Алмат' AND
InventDim.ECC_BUSINESSUNITID = 'Казахстан';
El plan de consulta (con TOP):
La consulta de estadísticas IO y TIME (con TOP):
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
(0 row(s) affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'INVENTTRANS'. Scan count 15385, logical reads 82542, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'INVENTDIM'. Scan count 1, logical reads 62704, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 265 ms, elapsed time = 257 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Los índices utilizados (con TOP):
1. INVENTTRANS.I_177TRANSIDIDX
4 KEYS:
- DATAAREAID
- INVENTTRANSID
- INVENTDIMID
- RECID
2. INVENTTRANS.I_177DIMIDIDX
3 KEYS:
- DATAAREAID
- INVENTDIMID
- ITEMID
3. INVENTDIM.I_698DIMIDIDX
2 KEYS:
- DATAAREAID
- INVENTDIMID
4. INVENTDIM.I_698ECC_BUSUNITLOCIDX
3 KEYS
- DATAAREAID
- ECC_BUSINESSUNITID
- INVENTLOCATIONID
¡Apreciará profundamente cualquier ayuda sobre el tema!
Respuestas:
SQL Server crea diferentes planes de ejecución para TOP 100, utilizando un algoritmo de ordenación diferente. A veces es más rápido, a veces es más lento.
Para ver ejemplos más simples, lea ¿Cuánto puede una fila cambiar un plan de consulta? Parte 1 y Parte 2 .
Para obtener detalles técnicos detallados, además de un ejemplo de dónde el algoritmo TOP 100 es realmente más lento, lea la Clasificación de Paul White, los Objetivos de fila y el Problema TOP 100 .
La conclusión: en su caso, si sabe que no se devolverán filas, bueno ... no ejecute la consulta, ¿eh? La consulta más rápida es la que nunca haces. Sin embargo, si necesita hacer una verificación de existencia, simplemente haga SI EXISTE (consulta aquí), y luego SQL Server hará un plan de ejecución incluso diferente.
fuente
Mirando los dos planes, tiene una búsqueda clave en ambos con costos porcentualmente diferentes. Si pasa el mouse sobre los objetos, verá el número de ejecuciones.
La búsqueda de claves es una búsqueda de regreso al índice agrupado ya que el índice utilizado en la búsqueda de índice (arriba a la derecha) no cubre todas las columnas (seleccione *, por lo que debe usarse el índice agrupado).
Top 100 puede obtener las 100 filas necesarias en menos lecturas del índice y luego realizar la búsqueda 100 veces en lugar de cada fila de la tabla. También explica el aumento en el número de páginas leídas cuando NO se hace el 'top'.
fuente