To pytanie dotyczy wydajności indeksu SQL Server z indeksem zakrywającym varchar(2000)
jako INCLUDE
a.
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 indeksieINCLUDE
jest dobrym pomysłem?Ponieważ
INCLUDE
pola 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”.
VARCHAR(2000)
które zwykle przechowuje tylko dziesięć znaków, to jedno; Solidne 2000 bajtów na rekord to coś innego.