Prosta zagadka. Rozważmy następującą tabelą z dwoma kolumnami:
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.:
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.