Cosa significa veramente la parola "SARGable"?


23

Gli utenti di SQL Server usano il termine "sargable" . Mi chiedo se esiste una definizione oggettiva e agnostica senza tempo per "sargable".

Ad esempio, WHERE foo LIKE '%bar%'molti dicono che non è possibile effettuare il sarginamento , ma alcuni RDBMS sono in grado di utilizzare gli indici su tali query . Che cosa significa quindi "non sargable" ?

Altri riferimenti


5
Potresti sottolineare che la tua domanda non riguarda SQL Server ma piuttosto il termine " sargable ". La tua domanda faceva riferimento solo a SQL Server perché non è in grado di gestire predicati di ricerca "% wordhere%", mentre apparentemente lo sono altri RDBMS.
John aka hot2use,

Risposte:


31

Il termine "sargable" è stato introdotto per la prima volta da P. Griffiths Selinger et al. nel loro articolo del 1979 "Selezione del percorso di accesso in un sistema di gestione di database relazionali", pubblicato da ACM . Per i membri non ACM c'è una copia di quel documento su http://cs.stanford.edu/people/chrismre/cs345/rl/selinger.pdf

Il termine è definito in questo paragrafo:

Le scansioni dell'indice e del segmento 1 possono facoltativamente accettare una serie di predicati, chiamati argomenti di ricerca (o SARGS), che vengono applicati a una tupla prima che venga restituita al chiamante RSI 2 . Se la tupla soddisfa i predicati, viene restituita; in caso contrario la scansione continua fino a quando non trova una tupla che soddisfa il SARGS o esaurisce il segmento o l'intervallo di valori dell'indice specificato. Ciò riduce i costi eliminando il sovraccarico di effettuare chiamate RSI per le tuple che possono essere efficacemente rifiutate all'interno dell'RSS. Non tutti i predicati hanno la forma che può diventare SARGS. Un predicato di grandi dimensioni è uno di forma (o che può essere inserito nel modulo) "valore operatore comparativo colonna". I SARG sono espressi come espressione booleana di tali predicati in forma disgiuntiva normale.

In altre parole, un predicato di grandi dimensioni è tale che può essere risolto dal motore di archiviazione (metodo di accesso) osservando direttamente la tabella o il record dell'indice. Al contrario, un predicato non numerabile richiede un livello superiore del DBMS per agire. Ad esempio, il risultato di WHERE lastname = 'Doe'può essere deciso dal motore di archiviazione semplicemente guardando il contenuto del campo lastnamedi ciascun record. D'altra parte, WHERE UPPER(lastname) = 'DOE'richiede l'esecuzione di una funzione da parte del motore SQL, il che significa che il motore di archiviazione dovrà restituire tutte le righe che legge (purché corrispondano a possibili altri predicati di grandi dimensioni) al motore SQL per la valutazione, sostenendo costi aggiuntivi della CPU .

Dalla definizione originale si può vedere che i predicati di grandi dimensioni possono applicarsi non solo alle scansioni dell'indice, ma anche alle scansioni delle tabelle (segmento nella terminologia del sistema R), purché siano soddisfatte le condizioni "valore operatore comparativo di colonna" e pertanto possano essere valutato dal motore di archiviazione. Questo è davvero il caso di Db2, un discendente del Sistema R in molti modi :

I predicati di grandi dimensioni dell'indice non vengono utilizzati per raggruppare una ricerca, ma vengono valutati dall'indice se ne viene scelto uno, poiché le colonne coinvolte nel predicato fanno parte della chiave dell'indice. Questi predicati vengono inoltre valutati dal gestore dell'indice.

I predicati di grandi dimensioni dei dati sono predicati che non possono essere valutati dal gestore dell'indice, ma possono essere valutati da Data Management Services (DMS). In genere, questi predicati richiedono l'accesso a singole righe da una tabella di base. Se necessario, DMS recupererà le colonne necessarie per valutare il predicato,

Il fatto che nei predicati di grandi dimensioni di SQL Server-speak siano solo quelli che possono essere risolti utilizzando le ricerche di indice è probabilmente determinato dall'incapacità del suo motore di archiviazione di applicare tali predicati durante le scansioni delle tabelle.

I predicati di grandi dimensioni e non di grandi dimensioni sono talvolta descritti rispettivamente come predicati di "fase 1" e "fase 2" (questo deriva anche dalla terminologia Db2 ). I predicati della fase 1 possono essere valutati al livello più basso di elaborazione delle query, durante la lettura dei record di tabella o indice. Le righe che soddisfano le condizioni della fase 1, se presenti, vengono inviate al livello successivo, fase 2, della valutazione.


1 - Il segmento nel Sistema R è l'archiviazione fisica delle tuple di una tabella; una scansione di segmento è in qualche modo equivalente a una scansione di tabella in altri DBMS.

2 - RSI - RSS 3 Interface, un'interfaccia di query orientata alla tupla. La funzione di interfaccia rilevante per questa discussione è NEXT, che restituisce i predicati della query di corrispondenza della riga successiva.

3 - RSS, o Research Storage System, il sottosistema di archiviazione del sistema R.


"osservando direttamente la tabella o il record dell'indice" cosa significa? Voglio dire, certamente = UPPER()è una chiamata di funzione, ma lo è anche di memcmpper sé. Sarebbe relativamente facile scrivere un memcmpche assume ASCII e ignora il caso (basta guardare il secondo bocconcino). Questo lo rende SARAGABILE? Vedi anche l'esempio di @ Ypercube, dba.stackexchange.com/questions/162263/…
Evan Carroll,

4
@EvanCarroll Significa guardare direttamente la tabella o il record dell'indice, senza ricorrere alle funzioni del database implementate al di fuori del motore di archiviazione (ad es. All'interno del processore di query / motore di esecuzione / servizio di espressione). Nell'esempio di ypercube, la query viene preelaborata dal planner / ottimizzatore in modo tale che la ricerca non SARGable sia espressa in termini SARGable.
Paul White Ripristina Monica

Che cosa significa "guardare direttamente la tabella o il record dell'indice" ? Non sono sicuro di come sia spiegato "l'osservazione diretta della tabella o del record dell'indice" . È x=0SARGable? Che dire -0 = +0, ' ' = ''o l'uguaglianza spaziale? Quale sarebbe sicuramente un esempio di qualcosa che era SARGable? Quando dici "senza ricorrere a funzioni di database implementate al di fuori del motore di archiviazione", includi l'esempio di Ypercube DATE()che è incluso nel motore di archiviazione. Perché questo SARGable non è da solo?
Evan Carroll,

2
@EvanCarroll Prenditi un po 'di tempo per leggere il documento di riferimento, e forse ripassa questa risposta dopo. Se hai ancora domande su questo argomento, potresti farle. Nota di passaggio che DATE()non è una vera funzione (SQL Server), ma (presumo) la scorciatoia di Mr. Cube per una conversione di tipo. Possiamo anche discuterne in chat se vuoi.
Paul White Ripristina Monica

18

Per me, SARGable significa che SQL Server può eseguire una ricerca dell'indice utilizzando i predicati della ricerca.

Non si può semplicemente dire che il DBMS può "sfruttare" un indice, perché con un predicato non numerabile, SQL Server potrebbe finire con la scansione di un indice non cluster.


Vorrei estenderlo anche all'eliminazione delle partizioni
David Markודו Markovitz

9

Secondo Pro SQL Server Internals di Dmitri Korotkevitch :

Un predicato ABLE di Search ARgument è un predicato in cui SQL SERVER può utilizzare un'operazione di ricerca dell'indice, se esiste un indice.

Un predicato SARGable è un predicato in cui il server SQL può isolare il singolo valore o intervallo di valori chiave dell'indice da elaborare

Predicati SARGable includono i seguenti operatori: =, >, >=, <, <=, IN, BETWEEN, e LIKE( nel caso di allineamento prefisso )

Operatori non SARGable comprendono: NOT, NOT IN, <>, e LIKE( non del prefisso ), così come l'uso di funzioni o calcoli contro il tavolo, e conversioni di tipo in cui il tipo di dati non soddisfa l'indice creato.

Esempio :

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;

Ora corriamo:

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;

I risultati sono:

[1]

Diamo un'occhiata alle proprietà della query SARGable (Ricerca indice)

inserisci qui la descrizione dell'immagine

Query Optimizer è in grado di definire un limite nell'indice di inizio e fine. Ha un argomento di ricerca con cui interrogare.

Ora la query non SARGable:

inserisci qui la descrizione dell'immagine

È possibile vedere con l'inizio del predicato '% non ..%' non consentire a Query Optimizer di DEFINIRE un inizio, una fine o un intervallo nell'indice. Ora deve cercare in tutta la tabella (scansione).


Quindi, se in seguito viene creato un indice che supporta WHERE name like '%non-SARGable%'ciò rende la condizione rilevabile? E, in caso affermativo, non stiamo parlando di uno svantaggio di implementazione specifico? IE., Non dovremmo dire "non estendibile a partire da SQL Server 2016"
Evan Carroll

1
Sebbene tutto sia possibile nelle versioni di SQL Server. Tenendo presente il punto di non ritorno di un indice un carattere jolly all'inizio del predicato sarebbe molto difficile per l'ottimizzatore della query definire un intervallo di valori all'interno di un indice da cercare. Pertanto, utilizzando una scansione e il predicato viene quindi chiamato predicato non SARGable.
Vic lavora il

2
Naturalmente è specifica per l'implementazione. WHERE DATE(datetime_column) = '2001-01-01'ad esempio è "sargable" (farà la ricerca dell'indice) nelle versioni più recenti di SQL Server (credo 2008+) ma non in quelle precedenti.
ypercubeᵀᴹ
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.