Domanda sulle prestazioni "SELEZIONA TOP"


18

Ho una query che funziona molto più velocemente con select top 100e molto più lentamente senza top 100. Il numero di record restituiti è 0. Potresti spiegare la differenza nei piani di query o condividere collegamenti in cui tale differenza è spiegata?

La query senza toptesto:

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 = 'Казахстан';

Il piano di query per quanto sopra (senza top):

https://pastebin.com/cbtJpxFf

inserisci qui la descrizione dell'immagine

Le statistiche IO e TIME (senza 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.

Gli indici utilizzati (senza 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 query 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 = 'Казахстан';

Il piano di query (con TOP):

https://pastebin.com/0dyu6QZd

inserisci qui la descrizione dell'immagine


Le query IO e 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.

Gli indici utilizzati (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

Apprezzeremo profondamente qualsiasi aiuto sull'argomento!


2
Non credo che la velocità di "TOP" senza "ORDER BY" sia importante. I risultati corretti sono più importanti della velocità.
Dan Guzman,

Risposte:


15

SQL Server crea piani di esecuzione diversi per TOP 100, utilizzando un algoritmo di ordinamento diverso. A volte è più veloce, a volte è più lento.

Per esempi più semplici, leggi Quanto può una riga modificare un piano di query? Parte 1 e Parte 2 .

Per dettagli tecnici approfonditi, oltre a un esempio di dove l'algoritmo TOP 100 è effettivamente più lento, leggi l'ordinamento, gli obiettivi di fila e il problema TOP 100 di Paul White .

La linea di fondo: nel tuo caso, se sai che non verrà restituita alcuna riga, beh ... non eseguire la query, eh? La query più veloce è quella che non fai mai. Tuttavia, se è necessario eseguire un controllo di esistenza, eseguire IF EXISTS (stick query qui), quindi SQL Server eseguirà un piano di esecuzione persino diverso.


Grazie, lo leggerò sicuramente. Ho anche notato che le stime delle righe non sono corrette in entrambi gli scenari. A cosa potrebbe essere collegato? Le statistiche vanno bene - L'ho aggiornato con l'opzione fullscan su entrambi gli indici cluster.
George K,

Inoltre - è adatto nel mio caso in quanto non ho alcun ORDINE, quindi credo che non ci sarà ORDINE nel mio piano?
George K,

Sarà molto interessante vedere se il piano di esecuzione è lo stesso sia per TOP 100 che per TOP 101. Se è possibile, si prega di condividere. Grazie.
Artashes Khachatryan,

@GeorgeK Vedo che stai usando Dynamics AX. Fai attenzione al flag di traccia [ blogs.msdn.microsoft.com/axinthefield/… che può portare a molti problemi di stima. Se il flag di traccia 4136 è disabilitato, controlla se la colonna "Partizione" è la prima nei tuoi indici. La partizione ha di solito pochissimi valori distinti.
Hans Vader,

9

Guardando i due piani, hai una ricerca chiave su entrambi con costi% notevolmente diversi. Se passi il mouse sugli oggetti, vedrai il numero di esecuzioni.

La ricerca chiave è una ricerca nell'indice cluster poiché l'indice utilizzato nella ricerca dell'indice (in alto a destra) non copre tutte le colonne (selezionare *, quindi è necessario utilizzare l'indice cluster).

Top 100 è in grado di ottenere le 100 righe necessarie in meno letture dall'indice e quindi eseguire la ricerca 100 volte anziché per ogni riga della tabella. Spiega anche l'aumento del numero di pagine lette quando NON si fa il "top".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.