Eu tenho uma consulta que roda muito mais rápido com select top 100
e muito mais lento sem top 100
. O número de registros retornados é 0. Você poderia explicar a diferença nos planos de consulta ou compartilhar links onde essa diferença foi explicada?
A consulta sem 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 = 'Казахстан';
O plano de consulta para o acima (sem top
):
As estatísticas de IO e TIME (sem 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.
Os índices usados (sem 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
A consulta com 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 = 'Казахстан';
O plano de consulta (com TOP):
As estatísticas de IO e TIME da consulta (com 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.
Os índices usados (com 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 qualquer ajuda sobre o tema!
Respostas:
O SQL Server cria diferentes planos de execução para o TOP 100, usando um algoritmo de classificação diferente. Às vezes é mais rápido, às vezes é mais lento.
Para exemplos mais simples, leia Quanto uma linha pode alterar um plano de consulta? Parte 1 e Parte 2 .
Para detalhes técnicos detalhados, além de um exemplo de onde o algoritmo TOP 100 é realmente mais lento, leia Classificação, metas de linha e problema do TOP 100 , de Paul White .
A linha inferior: no seu caso, se você souber que nenhuma linha será retornada, bem ... não execute a consulta, hein? A consulta mais rápida é aquela que você nunca faz. No entanto, se você precisar fazer uma verificação de existência, faça IF EXISTS (consulte a consulta aqui) e o SQL Server executará um plano de execução ainda diferente.
fonte
Olhando para os dois planos, você tem uma pesquisa importante de ambos com custos% diferentes. Se você passar o mouse sobre os objetos, verá o número de execuções.
A pesquisa de chave é uma pesquisa de volta ao índice clusterizado, pois o índice usado na busca de índice (canto superior direito) não cobre todas as colunas (selecione * para que o índice clusterizado seja usado).
As 100 principais são capazes de obter as 100 linhas necessárias em menos leituras do índice e, em seguida, executar a pesquisa 100 vezes em vez de todas as linhas da tabela. Também explica o aumento no número de páginas lidas quando NÃO está no 'topo'.
fonte