Co tak naprawdę oznacza słowo „SARGable”?

23

Użytkownicy programu SQL Server używają terminu „sargable” . Zastanawiam się, czy istnieje obiektywna, ponadczasowa, niezależna od implementacji definicja „sargable”.

Na przykład WHERE foo LIKE '%bar%'wiele osób uważa , że nie można ich sprzedawać , ale niektóre RDBMS są w stanie używać indeksów do takich zapytań . Co zatem oznacza „niewymienny” ?

Inne referencje

Evan Carroll
źródło
5
Możesz wskazać, że twoje pytanie nie dotyczy SQL Servera, ale termin „ sargable ”. Twoje pytanie dotyczyło tylko programu SQL Server, ponieważ nie jest on w stanie obsłużyć predykatów wyszukiwania „% wordhere%”, podczas gdy najwyraźniej są inne RDBMS.
John aka hot2use,

Odpowiedzi:

31

Termin „sargable” został po raz pierwszy wprowadzony przez P. Griffithsa Selingera i in. w artykule z 1979 r. „Wybór ścieżki dostępu w systemie zarządzania relacyjnymi bazami danych”, opublikowanym przez ACM . Dla członków spoza ACM kopię tego dokumentu można znaleźć na stronie http://cs.stanford.edu/people/chrismre/cs345/rl/selinger.pdf

Termin jest zdefiniowany w tym akapicie:

Zarówno skanowanie indeksu, jak i segmentu 1 może opcjonalnie przyjmować zestaw predykatów, zwanych argumentami wyszukiwania (lub SARGS), które są stosowane do krotki przed jej zwróceniem do programu wywołującego RSI 2 . Jeśli krotka spełnia predykaty, jest zwracana; w przeciwnym razie skanowanie będzie kontynuowane, dopóki nie znajdzie krotki, która spełnia SARGS lub wyczerpuje segment lub określony zakres wartości indeksu. Zmniejsza to koszty, eliminując narzut związany z wykonywaniem wezwań RSI na krotki, które można skutecznie odrzucić w RSS. Nie wszystkie predykaty mają formę, która może stać się SARGS. Sargable orzeczenie jest jedną z postaci (lub które mogą być wprowadzone w formie) „kolumnę wartości porównawczej-operatora”. SARGS są wyrażane jako logiczna ekspresja takich predykatów w rozłącznej postaci normalnej.

Innymi słowy, orzeczenie podlegające wymianie jest takie, że może być rozwiązane przez silnik pamięci masowej (metoda dostępu) bezpośrednio obserwując tabelę lub rekord indeksu. I odwrotnie, orzeczenie niewymieralne wymaga wyższego poziomu DBMS, aby podjąć działanie. Na przykład o wyniku WHERE lastname = 'Doe'może decydować silnik pamięci masowej, po prostu patrząc na zawartość pola lastnamekażdego rekordu. Z drugiej strony WHERE UPPER(lastname) = 'DOE'wymaga wykonania funkcji przez silnik SQL, co oznacza, że ​​silnik pamięci będzie musiał zwrócić wszystkie odczytywane wiersze (pod warunkiem, że pasują one do innych przewidywalnych predykatów) z powrotem do silnika SQL w celu oceny, co spowoduje dodatkowe koszty procesora .

Z oryginalnej definicji można zobaczyć, że predykaty sargable mogą dotyczyć nie tylko skanów indeksu, ale także skanów tabel (segmentów w terminologii Systemu R), o ile spełnione są warunki „porównanie operatora z wartością kolumny” i dlatego mogą być oceniane przez silnik pamięci masowej. Tak jest w przypadku Db2, potomka Systemu R na wiele sposobów :

Predykaty indeksowalne do indeksu nie są używane do nawiasowania wyszukiwania, ale są oceniane na podstawie indeksu, jeśli jest wybrany, ponieważ kolumny zaangażowane w predykat są częścią klucza indeksu. Te predykaty są również oceniane przez menedżera indeksu.

Predykaty podlegające wymianie danych to predykaty, które nie mogą być ocenione przez menedżera indeksu, ale mogą być ocenione przez usługi zarządzania danymi (DMS). Zazwyczaj te predykaty wymagają dostępu do poszczególnych wierszy z tabeli podstawowej. W razie potrzeby DMS pobierze kolumny potrzebne do oceny predykatu,

O tym, że w SQL Server-mówionych przewidywalnych predykatach są tylko te, które można rozwiązać za pomocą wyszukiwania indeksowego, prawdopodobnie wynika z niezdolności silnika pamięci masowej do zastosowania takich predykatów podczas skanowania tabeli.

Predykaty możliwe do zdobycia i niewymienne są czasami określane odpowiednio jako predykaty „etap 1” i „etap 2” (wynika to również z terminologii Db2 ). Predykaty etapu 1 można oceniać na najniższym poziomie przetwarzania zapytania podczas odczytywania rekordów tabeli lub indeksu. Rzędy, które spełniają warunki etapu 1, jeśli występują, są wysyłane na następny poziom oceny, etap 2.


1 - Segment w Systemie R to fizyczne przechowywanie krotek tabeli; skanowanie segmentów jest nieco równoważne skanowaniu tabeli w innych DBMS.

2 - Interfejs RSI - RSS 3 , zorientowany na krotki interfejs zapytań. Właściwą dla tej dyskusji funkcją interfejsu jest DALEJ, która zwraca predykaty zapytania pasującego do następnego wiersza.

3 - RSS lub Research Storage System, podsystem pamięci systemu R.

mustaccio
źródło
„bezpośrednio obserwując tabelę lub indeks”, co to znaczy? Mam na myśli z pewnością = UPPER()wywołanie funkcji, ale memcmpsamo w sobie. Byłoby stosunkowo łatwo napisać, memcmpktóry zakłada ASCII i ignoruje wielkość liter (wystarczy spojrzeć na drugą końcówkę). Czy to czyni ZNAJOMEGO? Zobacz także przykład @ Ypercube, dba.stackexchange.com/questions/162263/…
Evan Carroll
4
@EvanCarroll Oznacza bezpośrednie spojrzenie na tabelę lub rekord indeksu, bez uciekania się do funkcji bazy danych zaimplementowanych poza silnikiem pamięci masowej (np. W procesorze zapytań / silniku wykonawczym / usłudze wyrażeń). W przykładzie ypercube zapytanie jest wstępnie przetwarzane przez planistę / optymalizator, tak że wyszukiwanie inne niż SARGable jest wyrażone w kategoriach SARGable.
Paul White przywraca Monikę
Co oznacza „bezpośrednie spojrzenie na tabelę lub indeks” ? Nie jestem pewien, jak to wyjaśnia „bezpośrednie obserwowanie tabeli lub indeksu” . Czy x=0SARGable? A co -0 = +0, ' ' = ''czy równość przestrzenny? Jaki byłby na przykład przykład SARGable? Kiedy mówisz „bez uciekania się do funkcji bazy danych zaimplementowanych poza silnikiem pamięci” , włączasz się do przykładu Ypercube, DATE()który jest zawarty w silniku pamięci. Dlaczego sama SARGable nie jest możliwa?
Evan Carroll,
2
@EvanCarroll Poświęć trochę czasu, aby przeczytać artykuł, do którego się odwołuje, i być może ponownie przejrzyj tę odpowiedź ponownie. Jeśli nadal masz pytania na ten temat, możesz je zadać. Zauważmy, że DATE()nie jest to prawdziwa funkcja (SQL Server), ale (przypuszczam) skrót pana Cube do konwersji typu. Możemy również omówić to na czacie, jeśli chcesz.
Paul White przywraca Monikę
18

Dla mnie SARGable oznacza, że ​​SQL Server może wykonywać wyszukiwanie indeksu przy użyciu predykatów wyszukiwania.

Nie można po prostu powiedzieć, że DBMS może „wykorzystać” indeks, ponieważ przy predykcie niewymieralnym SQL Server może skończyć skanowaniem indeksu nieklastrowanego.

Brent Ozar
źródło
Rozszerzyłbym to również na eliminację partycji
David Markודו Markovitz
9

Według danych wewnętrznych Pro SQL Server autorstwa Dmitrija Korotkevitcha :

Predykat ARGument wyszukiwania ABLE to taki, w którym SQL SERVER może korzystać z operacji wyszukiwania indeksu, jeśli indeks istnieje.

Predykat SARGable to taki, w którym SQL Server może izolować pojedynczą wartość lub zakres wartości kluczy indeksu do przetworzenia

SARGable predykaty obejmuje następujące podmioty: =, >, >=, <, <=, IN, BETWEEN, i LIKE( w przypadku dopasowywania przedrostka )

Operatorzy zakaz SARGable to: NOT, NOT IN, <>oraz LIKE( nie dopasowanie prefiksu ), a także korzystanie z funkcji lub obliczeń przed stołem i typ konwersji gdzie typ danych nie spełniają indeks utworzony.

Przykład :

WHERE name like 'SARGable%'
WHERE name like '%non-SARGable%'

Demo :

DROP TABLE dbo.Testing;
GO

CREATE TABLE Testing (
    WeirdDatatype   int NOT NULL,
    SomethingElse   char(200)
);

CREATE NONCLUSTERED INDEX IDX_ALWAYS_SARGable
    ON dbo.Testing( SomethingElse);

CREATE NONCLUSTERED INDEX IDX_NOT_ALWAYS_SARGable
    ON dbo.Testing(SomethingElse);

INSERT INTO dbo.Testing
        ( WeirdDatatype, SomethingElse )
SELECT TOP 1000 m.message_id, CONVERT(char(200), m.text)
FROM sys.messages AS m;

Teraz uruchamiamy:

SELECT *
FROM dbo.Testing AS t
WHERE  t.WeirdDatatype = 1001;
SELECT *
FROM dbo.Testing AS t
WHERE t.SomethingElse LIKE 'Line%'
SELECT *
FROM dbo.Testing AS t
WHERE t.SomethingElse LIKE '%Line%'
     AND t.WeirdDatatype = 1001;

Wyniki są następujące:

[1]

Spójrzmy na właściwości zapytania SARGable (Wyszukiwanie indeksu)

wprowadź opis zdjęcia tutaj

Optymalizator zapytań jest w stanie zdefiniować limit w indeksie początku i końca. Ma argument wyszukiwania do zapytania.

Teraz zapytanie inne niż SARGable:

wprowadź opis zdjęcia tutaj

Możesz zobaczyć, że na początku predykatu „% non ..%” nie pozwala optymalizatorowi zapytań na określenie początku i końca lub zakresu w indeksie. Musi teraz przeszukać całą tabelę (skan).

Vic Work
źródło
Więc ponownie, jeśli później zostanie utworzony indeks, który obsługuje, WHERE name like '%non-SARGable%'czy to powoduje, że warunek jest podatny na sprzedaż? A jeśli tak, to czy nie mówimy o konkretnej wadzie implementacji? IE., Czy nie powinniśmy powiedzieć „nie można sargable od SQL Server 2016”
Evan Carroll
1
Chociaż w wersjach SQL Server wszystko jest możliwe. Mając na uwadze punkt końcowy indeksu, symbol wieloznaczny na początku predykatu bardzo utrudniłby optymalizatorowi zapytania zdefiniowanie zakresu wartości w indeksie do wyszukania. Zatem użycie skanu i predykatu jest następnie nazywane predykatem innym niż SARGable.
Vic Work
2
Oczywiście jest to specyficzne dla implementacji. WHERE DATE(datetime_column) = '2001-01-01'na przykład jest „sargable” (będzie szukał indeksu) w nowszych wersjach SQL Server (chyba 2008+), ale nie w starszych.
ypercubeᵀᴹ