Один індекс чи два?


11

У таблиці в моїй базі даних створений такий індекс:

CREATE INDEX [idx_index1]
on [table1]
(col1, col2, col3)

Сервер пропонує наступний 'пропущений' індекс:

CREATE INDEX [idx_index2]
on [table1]
(col1, col2)
INCLUDE (col3, col4, col5, col6....)

Мені здається логічним змінити існуюче визначення індексу, щоб включити запропоновані стовпці, а не створювати новий індекс, який потрібно підтримувати. Запит, який вибирається на col1 і col2, може використовувати index1 так само ефективно, як і index2. Я правильний чи я, можливо, щось пропускаю?

Відповіді:


12

І так входить у мистецтво налаштування ефективності та стратегії індексування ...

Мені здається логічним змінити існуюче визначення індексу, щоб включити запропоновані стовпці

Я візьму вашу пропозицію і напишу визначення третього індексу:

create index [idx_index3]
on [table1] (col1, col2, col3)
include (col4, col5, col6....);

Це має бути CREATE INDEXтвердження, яке відповідає вашому цитованому твердженню.

Це дуже добре може бути розумним рішенням, але це залежить . Ось кілька прикладів, коли я кажу, що це залежить.

Якщо у вас є загальна навантаження, яка в основному складається з таких запитів:

select col1, col2, col3
from table1
where col1 = 1
and col2 = 2
and col3 = 3;

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

Але якщо у вас є навантаження, яка складається з запитів, як правило, таких:

select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2;

Тоді idx_index2було б розумно, оскільки це називається покривним індексом, що перешкоджає необхідності пошуку ключа назад до кластерного індексу (або пошуку RID назад до купи). Це некластеризоване визначення індексу охоплювало б виключно всі дані, які потребують запиту.

З вашою рекомендацією, він цілком підходить для запиту на зразок наступного:

select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2
and col3 = 3;

Вашою idx_index3рекомендацією буде індекс покриття, який задовольняє критеріям пошуку вищезазначеного запиту.

Справа, яку я намагаюся досягти, полягає в такому відокремленому питанні, на яке ми не можемо відповісти остаточно. Все залежить від того, яке загальне та часте навантаження. Звичайно, ви завжди можете визначити всі ці три індекси для обробки кожного типу вибіркового запиту, але тоді виникає сумнів у технічному обслуговуванні, яке потребуватиме постійного оновлення цих індексів (подумайте: ВСТАВКИ, ОНОВЛЕННЯ, ВИДАЛЕННЯ). Ось накладні показники.

Потрібно розчленувати та оцінити навантаження та визначити, де переваги будуть найкращими. Якщо перший вибірковий запит є найпоширенішим, на сьогоднішній день виконується десятки разів в секунду, і є дуже рідкісний запит, як третій зразок запиту, тоді не було б сенсу роздувати сторінки на рівні аркушів в індексі INCLUDEстовпчики без ключа. Все залежить від вашої завантаженості.

Якщо ви розумієте розсудливі стратегії індексації та розумієте вашу загальну завантаженість, застосувавши обидві, ви зможете придумати найкращий шлях.


Мені доведеться перетравити це деякий час, але це здається гарною відповіддю. Я припускаю, що було помилковим помилкою, що "індекс 3", який ви визначили, має col3 як стовпець рівності І включений стовпець?
paulH

Так :-) Хороший улов. Я це відредагував.
Томас Стрінгер

Не кажучи вже про те, що якщо в таблиці є лише знаки 1-6, досить нерозумно індексувати 1 та 2 та включати 3-5.
Кеннет Фішер

1
@KennethFisher - чому це було б нерозумно? Здається, це досить розумно, якщо це вимагає структура вашої бази даних та ваше навантаження. Наприклад, якщо у вас є запит, який вибирає стовпчики 1-5 на основі значень стовпців 1 і 2, і, можливо, стовпець 6 - це стовпець nvarchar (max), з яким ви не хочете розмивати свій індекс.
polH

1
@paulH Це, мабуть, лише моя думка, але в момент, коли ви додали достатньо стовпців, слід зазначити, що ваш індекс містить 90 +% ваших стовпців у таблиці, ви роздули свій індекс до того, що зайвий зчитується, щоб перейти до таблиці само по собі не все так важливо. Тепер, безумовно, є винятки .. якщо cols 1-5 - це все int, а col6 - varchar (max), я можу це зробити. Але взагалі я б дивився на ці ДУЖЕ ретельно.
Кеннет Фішер

7

Ви дійсно правильні і виявили, чому для DBA важливо завжди переглядати "пропозиції", висунуті відсутніми індексами DMV тощо.

Вважайте, що пропозиції, запропоновані відсутніми індексами DMV, висуваються ізольовано, це означає, що SQL Server вирішив, що індекс рекомендованої структури буде корисним для запиту, незалежно від того, які інші структури індексу вже можуть існувати.


3

Ще трохи про один із наслідків відповіді Томаса:

Він сказав:

Звичайно, ви завжди можете визначити всі ці три індекси для обробки кожного типу вибіркового запиту, але тоді виникає сумнів у технічному обслуговуванні, яке потребуватиме постійного оновлення цих індексів (подумайте: ВСТАВКИ, ОНОВЛЕННЯ, ВИДАЛЕННЯ). Ось накладні показники.

Отже, стає ще одним великим питанням: як часто оновлюється таблиця?

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

З іншого боку, розгляньте таблицю, яка оновлюється лише як частина налаштування веб-сайту - таблиця, що оновлюється НАДНІШНЯ для більшості значень, а значення, які нечасто додаються, - там уповільнення оновлень, як правило, не враховує. Декілька індексів можуть уповільнити відновлення індексів баз даних і повторне редагування, але поки вони досить швидкі, ДУЖЕ БЕЗКОШТОВНО: якщо кілька індексів прискорюють читання, перейдіть до цього.

Середнім випадком може бути таблиця, яка зазвичай оновлюється лише в пакетному процесі протягом ночі. Там уповільнення оновлення з декількох індексів не вплине на показники денного режиму - вони вплинуть лише на (1) час, який потрібно взяти, запуск цього нічного обслуговування пакету, (2) на продуктивність одночасних процесів і (3) час, необхідний для такі завдання обслуговування баз даних, як реорганізація індексу. Отже, поки процеси на цих 3 аренах працюють досить швидко для вас ... створіть індекси, які прискорюють запити.

HTH ...

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