Que signifie vraiment le mot «SARGable»?

23

Les utilisateurs de SQL Server utilisent le terme "sargable" . Je me demande s'il existe une définition intemporelle objective et indépendante de la mise en œuvre pour «sargable».

Par exemple, WHERE foo LIKE '%bar%'beaucoup disent que ce n'est pas sargable , mais certains SGBDR sont capables d'utiliser des index sur de telles requêtes . Que signifie alors "non contestable" ?

Autres références

Evan Carroll
la source
5
Vous voudrez peut-être souligner que votre question ne concerne pas SQL Server mais plutôt le terme « sargable ». Votre question ne faisait référence qu'à SQL Server car il n'était pas en mesure de gérer les prédicats de recherche «% wordhere%», contrairement à d'autres RDBMS.
John aka hot2use

Réponses:

31

Le terme «sargable» a été introduit pour la première fois par P. Griffiths Selinger et al. dans leur article de 1979 "Sélection du chemin d'accès dans un système de gestion de bases de données relationnelles", publié par ACM . Pour les non-membres de l'ACM, il existe une copie de ce document à http://cs.stanford.edu/people/chrismre/cs345/rl/selinger.pdf

Le terme est défini dans ce paragraphe:

Les analyses d' index et de segment 1 peuvent éventuellement prendre un ensemble de prédicats, appelés arguments de recherche (ou SARGS), qui sont appliqués à un tuple avant qu'il ne soit renvoyé à l' appelant RSI 2 . Si le tuple satisfait les prédicats, il est retourné; sinon, le balayage continue jusqu'à ce qu'il trouve un tuple satisfaisant au SARGS ou épuise le segment ou la plage de valeurs d'index spécifiée. Cela réduit les coûts en éliminant les frais généraux liés aux appels RSI pour les tuples qui peuvent être efficacement rejetés dans le RSS. Tous les prédicats n'ont pas la forme qui peut devenir SARGS. Un prédicat sargable est celui de la forme (ou qui peut être mis dans le formulaire) "valeur d'opérateur de comparaison de colonne". SARGS sont exprimés comme une expression booléenne de ces prédicats sous forme normale disjonctive.

En d'autres termes, un prédicat sargable est tel qu'il peut être résolu par le moteur de stockage (méthode d'accès) en observant directement la table ou l'enregistrement d'index. Un prédicat non-sargable, à l'inverse, nécessite un niveau supérieur du SGBD pour agir. Par exemple, le résultat de WHERE lastname = 'Doe'peut être décidé par le moteur de stockage en regardant simplement le contenu du champ lastnamede chaque enregistrement. D'un autre côté, WHERE UPPER(lastname) = 'DOE'nécessite l'exécution d'une fonction par le moteur SQL, ce qui signifie que le moteur de stockage devra renvoyer toutes les lignes qu'il lit (à condition qu'elles correspondent à d'autres prédicats possibles, sargables) au moteur SQL pour évaluation, entraînant des coûts CPU supplémentaires .

Vous pouvez voir dans la définition d'origine que les prédicats sargables peuvent s'appliquer non seulement aux analyses d'index, mais également aux analyses de table (segment dans la terminologie System R), tant que les conditions "valeur d'opérateur de comparaison de colonnes" sont remplies et donc qu'elles peuvent être évalué par le moteur de stockage. C'est en effet le cas avec Db2, un descendant du système R à bien des égards :

Les prédicats pouvant être indexés ne sont pas utilisés pour mettre entre crochets une recherche, mais sont évalués à partir de l'index s'il est choisi, car les colonnes impliquées dans le prédicat font partie de la clé d'index. Ces prédicats sont également évalués par le gestionnaire d'index.

Les prédicats sargables de données sont des prédicats qui ne peuvent pas être évalués par le gestionnaire d'index, mais peuvent être évalués par les services de gestion des données (DMS). En règle générale, ces prédicats nécessitent l'accès à des lignes individuelles à partir d'une table de base. Si nécessaire, DMS récupérera les colonnes nécessaires pour évaluer le prédicat,

Le fait que, dans SQL Server, les prédicats sargables ne sont que ceux qui peuvent être résolus à l'aide de recherches d'index est probablement déterminé par l'incapacité de son moteur de stockage à appliquer ces prédicats pendant les analyses de table.

Les prédicats sargables et non négociables sont parfois décrits respectivement comme des prédicats "stade 1" et "stade 2" (cela provient également de la terminologie Db2 ). Les prédicats de l'étape 1 peuvent être évalués au plus bas niveau de traitement des requêtes, lors de la lecture des enregistrements de table ou d'index. Les lignes qui correspondent aux conditions de l'étape 1, le cas échéant, sont envoyées au niveau suivant, l'étape 2, de l'évaluation.


1 - Le segment dans le système R est le stockage physique des tuples d'une table; une analyse de segment est quelque peu équivalente à une analyse de table dans d'autres SGBD.

2 - RSI - RSS 3 Interface, une interface de requête orientée tuple. La fonction d'interface pertinente pour cette discussion est NEXT, qui renvoie les prédicats de requête correspondant à la ligne suivante.

3 - RSS, ou Research Storage System, le sous-système de stockage du système R.

mustaccio
la source
"observer directement la table ou l'enregistrement d'index" qu'est-ce que cela signifie? Je veux dire = UPPER()est certainement un appel de fonction, mais il en est memcmpde même en soi. Il serait relativement facile d'écrire un memcmpqui suppose ASCII et ignore la casse (il suffit de regarder le deuxième quartet). Est-ce que cela le rend SARGABLE? Voir également l'exemple de @ Ypercube, dba.stackexchange.com/questions/162263/…
Evan Carroll
4
@EvanCarroll Cela signifie regarder directement la table ou l'enregistrement d'index, sans recourir à des fonctions de base de données implémentées en dehors du moteur de stockage (par exemple au sein du processeur de requêtes / du moteur d'exécution / du service d'expression). Dans l'exemple de ypercube, la requête est prétraitée par le planificateur / optimiseur de telle sorte que la recherche non SARGable est exprimée en termes SARGable.
Paul White réintègre Monica
Que signifie «regarder directement la table ou l'enregistrement d'index» ? Je ne sais pas comment cela explique "l'observation directe de la table ou de l'index" . Est - x=0sargable? Qu'en est- il -0 = +0, ' ' = ''ou l' égalité spatiale? Quel serait un exemple de quelque chose qui était SARGable, c'est sûr? Lorsque vous dites «sans recours aux fonctions de base de données implémentées en dehors du moteur de stockage», vous incluez l'exemple de Ypercube DATE()qui est inclus dans le moteur de stockage. Pourquoi n'est-ce pas SARGable en soi?
Evan Carroll,
2
@EvanCarroll Prenez le temps de lire l'article référencé, et peut-être relisez cette réponse après cela. Si vous avez encore des questions sur le sujet ici, vous pouvez les poser. Notez en passant que ce DATE()n'est pas une vraie fonction (SQL Server), mais (je suppose) le raccourci de M. Cube pour une conversion de type. Nous pouvons également en discuter dans le chat si vous le souhaitez.
Paul White réintègre Monica
18

Pour moi, SARGable signifie que SQL Server peut effectuer une recherche d'index à l'aide de vos prédicats de recherche.

Vous ne pouvez pas simplement dire que le SGBD peut "tirer parti" d'un index, car avec un prédicat non sargable, SQL Server peut finir par analyser un index non cluster.

Brent Ozar
la source
Je voudrais également étendre cela à l'élimination des partitions
David דודו Markovitz
9

Selon Pro SQL Server Internals de Dmitri Korotkevitch :

Un prédicat Search ARgument ABLE est celui où SQL SERVER peut utiliser une opération de recherche d'index, s'il existe un index.

Un prédicat SARGable est celui où SQL Server peut isoler la valeur unique ou la plage de valeurs de clé d'index à traiter

Prédicats sargable comprennent les opérateurs suivants: =, >, >=, <, <=, IN, BETWEEN, et LIKE( dans le cas de mise en correspondance de préfixe )

Les opérateurs non sargable comprennent: NOT, NOT IN, <>et LIKE( pas correspondance préfixe ), ainsi que l'utilisation des fonctions ou des calculs sur la table, et les conversions de type où le type de données ne remplit pas l'index créé.

Exemple :

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

Démo :

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;

Maintenant, nous courons:

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;

Les résultats sont:

[1]

Regardons les propriétés de la requête SARGable (Index Seek)

entrez la description de l'image ici

L'optimiseur de requêtes est capable de définir une limite dans l'index de début et de fin. Il a un argument de recherche avec lequel interroger.

Maintenant, la requête non SARGable:

entrez la description de l'image ici

Vous pouvez voir qu'au début du prédicat '% non ..%' ne permet pas à l'optimiseur de requête de DÉFINIR un début et une fin ou une plage dans l'index. Il doit maintenant rechercher toute la table (scan).

Vic Work
la source
Encore une fois, si un index est créé ultérieurement qui prend en charge WHERE name like '%non-SARGable%'cela rend-il la condition sargable? Et, dans l'affirmative, ne parlons-nous pas d'un inconvénient d'implémentation spécifique? IE., Ne devrions-nous pas dire "non sargable à partir de SQL Server 2016"
Evan Carroll
1
Bien que tout soit possible dans les versions de SQL Server. Tout en gardant à l'esprit le point de basculement d'un index, un caractère générique au début du prédicat, il serait très difficile pour l'optimiseur de requête de définir une plage de valeurs dans un index à rechercher. Ainsi, l'utilisation d'un balayage et le prédicat est alors appelé prédicat non SARGable.
Vic Work du
2
Bien sûr, c'est spécifique à l'implémentation. WHERE DATE(datetime_column) = '2001-01-01'par exemple, est "sargable" (fera la recherche d'index) dans les nouvelles versions de SQL Server (2008+ je pense) mais pas dans les anciennes.
ypercubeᵀᴹ