web-dev-qa-db-fra.com

Qu'est-ce qui rend une instruction SQL sargable?

Par définition (du moins d'après ce que j'ai vu), sargable signifie qu'une requête est capable de faire en sorte que le moteur de requête optimise le plan d'exécution utilisé par la requête. J'ai essayé de chercher les réponses, mais il ne semble pas y avoir beaucoup de choses sur le sujet. La question est donc: qu'est-ce qui rend ou non une requête SQL sargable? Toute documentation serait grandement appréciée.

Pour référence: SARGable

234
DForck42

La chose la plus commune qui rendra une requête non sargable est d'inclure un champ à l'intérieur d'une fonction dans la clause where:

SELECT ... FROM ...
WHERE Year(myDate) = 2008

L'optimiseur SQL ne peut pas utiliser d'index sur myDate, même s'il en existe un. Il devra littéralement évaluer cette fonction pour chaque ligne du tableau. Bien mieux utiliser:

WHERE myDate >= '01-01-2008' AND myDate < '01-01-2009'

Quelques autres exemples:

Bad: Select ... WHERE isNull(FullName,'Ed Jones') = 'Ed Jones'
Fixed: Select ... WHERE ((FullName = 'Ed Jones') OR (FullName IS NULL))

Bad: Select ... WHERE SUBSTRING(DealerName,4) = 'Ford'
Fixed: Select ... WHERE DealerName Like 'Ford%'

Bad: Select ... WHERE DateDiff(mm,OrderDate,GetDate()) >= 30
Fixed: Select ... WHERE OrderDate < DateAdd(mm,-30,GetDate()) 
237
BradC

Ne fais pas ça:

WHERE Field LIKE '%blah%'

Cela provoque une analyse table/index, car la valeur LIKE commence par un caractère générique.

Ne fais pas ça:

WHERE FUNCTION(Field) = 'BLAH'

Cela provoque une analyse de table/index.

Le serveur de base de données devra évaluer FUNCTION () par rapport à chaque ligne du tableau, puis le comparer à "BLAH".

Si possible, faites-le à l'envers:

WHERE Field = INVERSE_FUNCTION('BLAH')

Cela exécutera INVERSE_FUNCTION () avec le paramètre une fois et autorisera néanmoins l'utilisation de l'index.

75
beach

Dans cette réponse, je suppose que la base de données contient suffisamment d'index de couverture. Il y a suffisamment de questions sur ce sujet .

Souvent, la sargabilité d'une requête est déterminée par le point de basculement des index liés. Le point de basculement définit la différence entre la recherche et l'analyse d'un index lorsque vous joignez une table ou un jeu de résultats à une autre. Une recherche est bien sûr beaucoup plus rapide que de parcourir une table entière, mais lorsque vous devez rechercher beaucoup de lignes, une analyse peut avoir plus de sens.

Ainsi, entre autres choses, une instruction SQL est plus sargable lorsque l'optimiseur s'attend à ce que le nombre de lignes résultantes d'une table soit inférieur au point de basculement d'un index possible sur la table suivante.

Vous pouvez trouver un article détaillé et un exemple ici .

9

Pour qu'une opération soit considérée comme sargable, il ne suffit pas qu'elle puisse simplement utiliser un index existant. Dans l'exemple ci-dessus, l'ajout d'un appel de fonction à une colonne indexée dans la clause where permettrait toujours de tirer parti de l'index défini. Il "analysera", c’est-à-dire récupérera toutes les valeurs de cette colonne (index), puis éliminera celles qui ne correspondent pas à la valeur de filtre fournie. Il n'est toujours pas assez efficace pour les tables avec un nombre élevé de lignes. Ce qui définit vraiment la sargabilité, c'est la capacité de la requête à parcourir l'index du b-tree à l'aide de la méthode de recherche binaire qui repose sur l'élimination à demi-ensemble du tableau d'éléments triés. En SQL, il serait affiché sur le plan d'exécution en tant que "recherche d'index".

4
user2011845