web-dev-qa-db-fra.com

Que signifie vraiment le mot «SARGable»?

Utilisateurs de SQL Server tilisez 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%' est considéré par beaucoup comme ( non discutable , mais certains SGBDR sont capables d'utiliser des index sur de tels requêtes . Que signifie alors "non sargable" ?

Autres références

26
Evan Carroll

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:

Index et segment1 les analyses 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é au RSI2 votre interlocuteur. 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 un de 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 lastname de 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 l'évaluation, entraînant des coûts CPU supplémentaires.

Vous pouvez voir d'après 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 Data Management Services (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 vient aussi de 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 - RSS3 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.

34
mustaccio

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.

19
Brent Ozar

Selon Pro SQL Server Internals par 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

Les prédicats SARGable incluent les opérateurs suivants: =, >, >=, <, <=, IN, BETWEEN et LIKE ( dans le cas d'une correspondance de préfixe)

Les opérateurs non SARGables incluent: NOT, NOT IN, <> et LIKE ( pas de correspondance de préfixe), ainsi que l'utilisation de fonctions ou de calculs sur la table, et tapez des conversions 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)

enter image description here

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:

enter image description here

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).

11
Vic Work