Питання про ефективність "SELECT TOP"


18

У мене є запит, який працює набагато швидше з select top 100і набагато повільніше без top 100. Кількість повернених записів дорівнює 0. Чи можете ви пояснити різницю в планах запитів або спільних посиланнях, де пояснюється така різниця?

Запит без 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 = 'Казахстан';

План запитів для вищезазначених (без top):

https://pastebin.com/cbtJpxFf

введіть тут опис зображення

Статистика IO та TIME (без 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.

Використовувані індекси (без 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

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

План запитів (з TOP):

https://pastebin.com/0dyu6QZd

введіть тут опис зображення


Статистика запиту IO та TIME (з 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.

Використовувані індекси (з 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

Будемо глибоко вдячні за будь-яку допомогу з цієї теми!


2
Я не думаю, що швидкість "ТОП" без "ЗАМОВЛЕННЯ" має значення. Правильні результати важливіші за швидкість.
Дан Гузман

Відповіді:


15

SQL Server будує різні плани виконання для ТОП 100, використовуючи інший алгоритм сортування. Іноді швидше, іноді повільніше.

Для простіших прикладів цього читання читайте, наскільки може один рядок змінити план запитів? Частина 1 та частина 2 .

Для отримання поглиблених технічних деталей, а також прикладу того, де алгоритм ТОП насправді повільніше, читайте Сортування Пола Уайта, Цілі рядків та Проблема ТОП-100 .

Суть: у вашому випадку, якщо ви знаєте, що жодні рядки не повернуться, ну ... не запускайте запит, так? Найшвидший запит - це той, який ти ніколи не робиш. Однак якщо вам потрібно зробити перевірку існування, просто зробіть IF EXISTS (дотримуйтесь запит тут), і тоді SQL Server складе ще інший план виконання.


Дякую, я обов'язково прочитаю. Я також помітив, що в обох сценаріях оцінки рядків невірні. З чим це може бути пов’язано? Статистика, якщо добре - я оновив її опцією повноекранності на обох кластерних індексах.
Джордж К

Також - чи підходить воно в моєму випадку, оскільки я не маю жодного ЗАМОВЛЕННЯ, тож я вважаю, що в моєму плані немає СОРТ?
Джордж К

Буде дуже цікаво дізнатись, чи однаковий план виконання як для ТОП 100, так і для ТОП 101. Якщо це можливо, будь ласка, поділіться. Спасибі.
Арташес Хачатрян

@GeorgeK Я бачу, що ви використовуєте Dynamics AX. Слідкуйте за прапором слідів [ blogs.msdn.microsoft.com/axinthefield/…, який може призвести до багатьох проблем з оцінкою. Якщо прапор сліду 4136 відключений, перевірте, чи стовпець "Розділ" є першим у ваших індексах. У розділі зазвичай дуже мало чітких значень.
Ганс Вейдер

9

Дивлячись на два плани, у вас є ключовий пошук обох із різко різними% витратами. Якщо навести курсор миші на об'єкти, ви побачите кількість страт.

Пошук ключів - це пошук назад до кластеризованого індексу, оскільки індекс, що використовується в пошуку індексу (угорі праворуч), не охоплює всіх стовпців (виберіть *, тому кластерний індекс повинен бути використаний).

Топ-100 може отримати 100 рядків, необхідних для меншого читання з індексу, а потім виконати пошук у 100 разів, а не для кожного рядка таблиці. Також пояснюється збільшення кількості прочитаних сторінок, коли НЕ роблять "верх".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.