W jaki sposób duże pola INCLUDE wpłyną na wydajność systemu?

15

To pytanie dotyczy wydajności indeksu SQL Server z indeksem zakrywającym varchar(2000)jako INCLUDEa.

Próbuję poprawić wydajność w powolnej i niestabilnej aplikacji bazy danych. W niektórych przypadkach dane są dostępne za pośrednictwem dużych ciągów varchar, z zapytaniami w tym multple operacji strunowych, takich jak SUBSTRING(), SPACE()i DATALENGTH(). Oto uproszczony przykład dostępu;

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

Schemat wygląda następująco:

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, ... 

Zdefiniowano następujący indeks z zakrywającym polem w dużej kolumnie tekstowej.

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

Z tego, co przeczytałem, ZŁE jest umieszczanie dużych pól danych w indeksie. Czytałem kilka artykułów, w tym http://msdn.microsoft.com/en-us/library/ms190806.aspx, które omawiają wpływ stronicowania i rozmiaru dysku na wydajność indeksu. To powiedziawszy, plan zapytań zdecydowanie używa indeksu obejmującego. Nie mam wystarczających informacji, aby ustalić, ile faktycznie mnie to kosztuje pod względem obciążenia systemu. Wiem, że ogólnie system działa słabo i martwię się, że jest to jeden z problemów. Pytania:

  • Czy umieszczenie tej varchar(2000)kolumny w indeksie INCLUDEjest dobrym pomysłem?

  • Ponieważ INCLUDEpola są przechowywane w węzłach liści, czy mają one duży wpływ na indeks wydajności?

Aktualizacja: Dziękujemy za doskonałe odpowiedzi! Jest to w pewnym sensie niesprawiedliwe pytanie - jak mówicie, nie ma absolutnie właściwej odpowiedzi bez faktycznych statystyk i profilowania. Podobnie jak w przypadku wielu problemów z wydajnością, odpowiedź brzmi „to zależy”.

RaoulRubin
źródło
Jak długie są rzeczywiste wartości? A, VARCHAR(2000)które zwykle przechowuje tylko dziesięć znaków, to jedno; Solidne 2000 bajtów na rekord to coś innego.
Jon of All Trades
Tylko spostrzeżenie: coś, co „pachnie” tutaj, polega na tym, że duża kolumna może zawierać albo 1) dowolny tekst, w którym to przypadku zapytania mogą skorzystać z przepisania w celu użycia indeksu FULLTEXT lub 2) zakodowanych danych „czytelnych dla człowieka” (np. Szeroki inteligentny klucze, takie jak VIN), które mogłyby skorzystać z podziału na osobne kolumny lub utrwalone kolumny obliczeniowe z INDEKSAMI. Innymi słowy, przepływ danych wywiadowczych i zmian danych nie jest dobrze zaprojektowany.
Graeme,
1
Tak #Graeme, tutaj jest nieprzyjemny zapach - myślę, że nazywa się to „dziedzictwem”. Istnieje wiele problemów w tych bazach danych.
RaoulRubin

Odpowiedzi:

14

Zawsze jest wielkie słowo, ale generalnie nie, nie umieściłbym pola varchar (2000) w polu INCLUDE.

I tak, sposób przechowywania danych na poziomie strony może poważnie wpłynąć na wydajność indeksu, w zależności od sposobu użycia indeksu.

Chodzi o to, że im więcej wierszy danych można wcisnąć na stronę, tym mniej stron trzeba uzyskać dostęp, tym szybciej system jest przeważnie. Dodanie naprawdę dużej kolumny oznacza mniej informacji przechowywanych na stronie, więc w przypadku szukania zasięgu lub skanowania potrzeba więcej stron do odczytania w celu odzyskania danych, co znacznie spowalnia pracę.

Aby się upewnić, czy jest to problem w zapytaniu lub w systemie, należy monitorować odczyty, zwłaszcza liczbę stron używanych przez zapytanie.

Grant Fritchey
źródło
Dzięki, Grant. Jak wspomniałem o innym komentarzu, dobrych informacji o wydajności jest mało, stąd abstrakcyjne pytanie. Nie mam doświadczenia w monitorowaniu kosztów wydajności rozmiaru strony. Mam przeczucie, że to jest problem, zobaczę, czy mogę zdobyć statystyki.
RaoulRubin
1
ustawienie statystyki We / Wy dla zapytania powie wiele, logiczne odczyty reprezentują liczbę odwiedzonych stron. Możesz także monitorować sekundy / odczyt z liczników perfmon, aby uzyskać ogólne informacje o wydajności.
Grant Fritchey,
6

Czy możesz przejrzeć aktualny klastrowany klucz indeksu i być może utworzyć col2klastrowany klucz indeksu? W ten sposób otrzymujesz zachowanie „uwzględnij” (ponieważ indeksy klastrowe są zawsze „obejmujące” wszystko) bez duplikowania danych. Jest to oczywiście przedmiotem wielu ifi butmimo to być może warto je rozważyć. Oczywiście, jeśli bieżący indeks klastrowy wymusza ograniczenie (klucz podstawowy, unikalny), wspomniane ograniczenie musiałoby zostać przeniesione do indeksu nieklastrowego.

Remus Rusanu
źródło
Twoja sugestia dotycząca PK jest świetnym pomysłem, chociaż nie będę w stanie zastosować go w tym przypadku - istniejące PK jest konieczne w przypadku innych zapytań. (To technika, którą trzymam w przyborniku!)
RaoulRubin
4

Trudno odpowiedzieć. Wszystko będzie zależeć od twojego współczynnika odczytu: zapisu. Czy przetestowałeś obciążenie pracą lub symulowałeś cały cykl biznesowy w systemie testowym z dołączoną kolumną i bez niej? Wyszukiwanie bez niego może kosztować dużo, ale jeśli aktualizujesz dane częściej niż je czytasz, może to być w porządku.

Aaron Bertrand
źródło
Ogólny odczyt w porównaniu z aktualizacją jest w większości zrównoważony. Problemy organizacyjne i związane z prywatnością utrudniają uzyskanie przydatnych statystyk i realistycznych testów. Ponieważ latamy głównie na ślepo, musimy patrzeć na rzeczy z abstrakcyjnego punktu widzenia (stąd to pytanie). Testowanie będzie oznaczało wprowadzanie zmian w produkcji i obserwowanie wyników - bardzo ryzykowne.
RaoulRubin
2
I czy większość odczytów faktycznie pobiera tę VARCHAR(2000)kolumnę, czy też rozwiązujesz problemy z wydajnością bardzo konkretnego zapytania, które nie reprezentuje większości zapytań? Jak sugeruje Grant, jeśli ta kolumna nie jest używana w wielu zapytaniach lub naprawdę powoduje problemy podczas wyszukiwania, prawdopodobnie lepiej będzie zapłacić cenę za wyszukiwanie, gdy jest to potrzebne, ale nie płacić za miejsce, gdy nie jest potrzebne . Ponownie, naprawdę trudno jest powiedzieć, po której stronie ogrodzenia powinieneś być, ponieważ tak naprawdę nie mamy żadnych szczegółów (a nawet trudniejszych, ponieważ nie możesz przetestować - powinieneś spróbować to naprawić).
Aaron Bertrand
3

Wiem, że jestem spóźniony na tę imprezę, ale indeksowałbym dokładnie wyrażenia użyte do zlokalizowania wierszy, takie jak podłańcuch (kol3,10,1). Jeśli kiedykolwiek użyje się całego col3, zaindeksowałbym CHECKSUM (col3) (rozumiejąc, że oczywiście mogą wystąpić kolizje).

AK
źródło