18/09/2013

Indeksy, LIKE oraz =


Prosta zagadka. Rozważmy następującą tabelą z dwoma kolumnami:
CREATE TABLE Test
(
   ID Int IDENTITY(1,1) PRIMARY KEY,
   Name CHAR(10)
)

CREATE INDEX IX_TEST_NAME ON dbo.Test (Name)
Teraz na wejściu dostajemy pewien ciąg znaków i przechowujemy go w zmiennej:
DECLARE @Variable CHAR(10);
SET @Variable = '1234567890';
Chcemy znaleźć wszystkie te rekordy, dla których N pierwszych znaków w kolumnie Name jest takie samo jak N pierwszych znaków w zadanym ciągu. Można to zrobić tak (N=3):
SELECT * FROM dbo.Test WHERE  LEFT(Name, 3) = LEFT(@Variable, 3)
Albo tak:
SELECT * FROM dbo.Test WHERE Name LIKE LEFT(@Variable, 3)+'%'
Oba zapytania dadzą ten sam wynik ale jedno z nich będzie zdecydowanie szybsze (dla dużej ilości danych) niż drugie. Które?

W tym przypadku użycie LIKE okazuje się lepszym wyborem. Dlaczego? W pierwszym zapytaniu zostanie użyty INDEX SCAN (czyli de facto odczytane zostaną wszystkie wiersze z tabeli), a w drugim  INDEX SEEK. Dzieje się tak gdyż w pierwszym zapytaniu użyto funkcji LEFT (może to być dowolna inna funkcja) na kolumnie, na której nałożony jest indeks.

Do problemu można też podejść w inny sposób czyli stworzyć indeks na kolumnie wyliczanej tj.:
ALTER TABLE dbo.Test ADD NAME2 AS LEFT(Name, 3)
CREATE INDEX IX_TEST_NAME2 ON dbo.Test(Name2, Name)
W takiej sytuacji pierwsze z pokazanych zapytań (te z operatorem =) również użyje operacji INDEX SEEK.

No comments:

Post a Comment