Pertanyaan kinerja 'SELECT TOP'

18

Saya memiliki kueri yang berjalan lebih cepat dengan memilih top 100dan lebih lambat tanpa top 100. Jumlah catatan yang dikembalikan adalah 0. Bisakah Anda menjelaskan perbedaan dalam rencana kueri atau berbagi tautan di mana perbedaan tersebut dijelaskan?

Permintaan tanpa topteks:

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

Paket permintaan untuk yang di atas (tanpa top):

https://pastebin.com/cbtJpxFf

masukkan deskripsi gambar di sini

Statistik IO dan TIME (tanpa 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.

Indeks yang digunakan (tanpa 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

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

Paket kueri (dengan TOP):

https://pastebin.com/0dyu6QZd

masukkan deskripsi gambar di sini


Statistik kueri IO dan WAKTU (dengan 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.

Indeks yang digunakan (dengan 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

Akan sangat menghargai bantuan apa pun tentang topik ini!

George K.
sumber
2
Saya tidak berpikir kecepatan 'TOP' tanpa 'ORDER BY' penting. Hasil yang benar lebih penting daripada kecepatan.
Dan Guzman
3
Terkait: mungkin duplikat Bagaimana (dan mengapa) TOP mempengaruhi rencana eksekusi?
Paul White mengatakan GoFundMonica

Jawaban:

15

SQL Server membangun rencana eksekusi yang berbeda untuk TOP 100, menggunakan algoritma pengurutan yang berbeda. Terkadang lebih cepat, kadang lebih lambat.

Untuk contoh yang lebih sederhana, bacalah Berapa Banyak yang Dapat Mengubah Satu Baris Rencana Kueri? Bagian 1 dan Bagian 2 .

Untuk detail teknis yang lebih mendalam, ditambah contoh di mana algoritma TOP 100 sebenarnya lebih lambat, baca Penyortiran Paul White, Row Goals, dan Masalah TOP 100 .

Intinya: dalam kasus Anda, jika Anda tahu bahwa tidak ada baris yang akan dikembalikan, well ... jangan jalankan kueri, eh? Permintaan tercepat adalah yang Anda tidak pernah buat. Namun, jika Anda perlu melakukan pemeriksaan keberadaan, lakukan JIKA ADA (tongkat permintaan di sini), dan kemudian SQL Server akan melakukan rencana eksekusi yang bahkan berbeda.

Brent Ozar
sumber
Terima kasih, saya pasti akan membacanya. Saya juga memperhatikan bahwa estimasi baris tidak benar di kedua skenario. Dengan apa terhubung? Statistik jika baik - saya telah memperbaruinya dengan opsi fullscan pada kedua indeks berkerumun.
George K
Juga - apakah ini cocok dalam kasus saya karena saya tidak memiliki PESANAN, jadi saya percaya tidak ada SORT yang akan ada dalam rencana saya?
George K
Akan sangat menarik untuk melihat apakah rencana eksekusi sama untuk TOP 100 dan TOP 101. Jika memungkinkan, silakan bagikan. Terima kasih.
Artashes Khachatryan
@ GeorgeK Saya dapat melihat bahwa Anda menggunakan Dynamics AX. Watch out for trace flag [ blogs.msdn.microsoft.com/axinthefield/… yang dapat menyebabkan banyak masalah perkiraan. Jika tanda jejak 4136 dinonaktifkan, periksa apakah kolom "Partisi" adalah yang pertama dalam indeks Anda. Partisi biasanya memiliki nilai yang sangat sedikit.
Hans Vader
9

Melihat kedua paket tersebut, Anda memiliki pencarian utama pada keduanya dengan% biaya yang sangat berbeda. Jika Anda mengarahkan mouse ke objek, Anda akan melihat jumlah eksekusi.

Pencarian kunci adalah pencarian kembali ke indeks berkerumun karena indeks yang digunakan dalam pencarian indeks (kanan atas) tidak mencakup semua kolom (pilih * sehingga indeks berkerumun harus digunakan).

Top 100 mampu mendapatkan 100 baris yang dibutuhkan dalam lebih sedikit bacaan dari indeks dan kemudian melakukan pencarian 100 kali daripada untuk setiap baris dalam tabel. Juga menjelaskan peningkatan jumlah halaman yang dibaca ketika TIDAK melakukan 'atas'.

Simon Hellings
sumber