Як великі поля з індексом INCLUDE вплинуть на продуктивність системи?


15

Це питання про продуктивність індексу SQL сервера з varchar(2000)як INCLUDEв індексі накриття.

Я намагаюся підвищити продуктивність у повільному та нестабільному додатку до бази даних. У деяких випадках доступ до даних здійснюється через великі рядки VARCHAR, з запитами , включаючи multple строкових операцій , як SUBSTRING(), SPACE(), і DATALENGTH(). Ось спрощений приклад доступу;

update fattable set col3 =  
   SUBSTRING(col3,1,10) + '*' + 
   SUBSTRING(col3,12,DATALENGTH(col3)-12)
from fattable where substring(col3,10,1) = 'A' and col2 = 2

Схема виглядає приблизно так:

CREATE TABLE [dbo].[FatTable]( 
    [id] [bigint] IDENTITY(1,1) NOT NULL, 
    [col1] [nchar](12) NOT NULL, 
    [col2] [int] NOT NULL, 
    [col3] [varchar](2000) NOT NULL, ... 

Визначений наступний індекс із полем покриття на великому текстовому стовпчику.

CREATE NONCLUSTERED INDEX [IndexCol2Col3] ON [dbo].[FatTable]  ( [col2] ASC ) 
    INCLUDE( [col3] )

З того, що я прочитав, це BAD ставити великі поля даних в індекс. Я читав кілька статей, серед яких http://msdn.microsoft.com/en-us/library/ms190806.aspx, в яких обговорюється вплив підкачки та розміру диска на продуктивність індексу. При цьому, план запитів, безумовно, використовує індекс покриття. У мене недостатньо інформації, щоб визначити, скільки це насправді коштує мені з точки зору завантаження системи. Я знаю, що в цілому система працює погано, і я стурбований тим, що це одне з питань. Запитання:

  • Чи ставити цей varchar(2000)стовпець в індекс INCLUDEзавжди корисною ідеєю?

  • Оскільки INCLUDEполя зберігаються у вузлах листів, чи мають вони великий показник впливу показника?

Оновлення: Дякую за чудові відповіді! Це в чомусь несправедливе запитання - як ви кажете, не існує абсолютної правильної відповіді без фактичної статистики та профілювання. Як і стільки питань щодо продуктивності, я думаю, що відповідь "це залежить".


Як довго тривають фактичні значення? VARCHAR(2000), Який зазвичай зберігає тільки десять символів одна річ; міцні 2000 байтів за запис - це щось інше.
Йон усіх торгів

Просто зауваження. Щось тут «пахне» - це те, що великий стовпець може містити або 1) вільний текст, і в цьому випадку запити можуть отримати користь від перезаписів, щоб використовувати індекс FULLTEXT, або 2) «читабельні людиною» закодовані дані (наприклад, широко інтелектуальні дані) ключі, як VIN), які могли б отримати користь від розбиття на окремі стовпці чи збережених обчислених стовпців з INDEXes. Іншими словами, потік інтелекту та змін даних недостатньо розроблений.
Graeme

1
Так # Граме, тут поганий запах - я думаю, це називається "спадщина". У цих базах даних існує безліч проблем.
RaoulRubin

Відповіді:


14

Колись це велике слово, але, загалом, ні, я б не вводив поле varchar (2000) у ВКЛЮЧЕНО.

Так, спосіб зберігання даних на рівні сторінки може серйозно вплинути на ефективність індексу, залежно від того, як використовується індекс.

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

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


Дякую Грант. Як я вже згадував ще один коментар, хорошої інформації про ефективність мало, звідси абстрактне питання. У мене немає досвіду моніторингу витрат на ефективність розміру сторінки. Моя думка полягає в тому, що це проблема, я побачу, чи зможу я отримати статистику.
RaoulRubin

1
встановлення IO статистики для запиту дозволить вам сказати багато, логічне зчитування відображає кількість доступних сторінок. Ви також можете стежити за секундами / читати з лічильників perfmon, щоб отримати загальну інформацію про продуктивність.
Грант Фрітчі

6

Чи можете ви переглянути поточний кластерний індексний ключ і, можливо, зробити col2 кластерний індексний ключ замість цього? Таким чином ви отримуєте поведінку покриття "включити" (оскільки кластерні індекси завжди "включаючи" все) без дублювання даних. Це, звичайно, підпорядковане багатьом ifі but, тим не менш, можливо, варто задуматися. Звичайно, якщо поточний кластерний індекс застосовує обмеження (первинний ключ, унікальний), зазначене обмеження потрібно буде перенести в некластеризований індекс.


Ваша пропозиція щодо ПК - це чудова ідея, хоча я не зможу застосувати її в цьому випадку - існуючий ПК необхідний для інших запитів. (Це техніка, яку я буду зберігати в панелі інструментів!)
RaoulRubin

4

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


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

2
І чи справді більшість прочитаних перетягує цей VARCHAR(2000)стовпець, або ви усуваєте проблеми з виконанням дуже конкретного запиту, який не представляє більшість запитів? Оскільки Грант пропонує, якщо цей стовпець не використовується у великій кількості запитів або справді викликає проблеми для запитів, ймовірно, буде краще заплатити ціну за пошук, коли вам це потрібно, але не платити за зберігання, коли ви цього не зробите . Знову ж таки, насправді важко сказати, на якій стороні паркану ви повинні опинитися, оскільки у нас насправді немає специфіки (а ще складніше, тому що ви не можете перевірити - ви повинні прагнути виправити це).
Аарон Бертран

3

Я знаю, що я запізнююся на цю партію, але я б індексував саме вирази, які використовуються для розміщення рядків, наприклад, підрядка (col3,10,1). Якщо весь col3 коли-небудь буде використаний, я би індексував CHECKSUM (col3) (розуміючи, що, звичайно, можуть бути зіткнення).

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