L'utilisation de la logique NOT par rapport aux index

12

Selon le livre de Microsoft sur le développement de bases de données Examen 70-433: Développement de bases de données Microsoft SQL Server 2008 :

Ni les caractères génériques de tête ni la logique NOT ne permettent à l'optimiseur de requête d'utiliser des index pour optimiser la recherche. Pour des performances optimales, vous devez éviter d'utiliser le mot clé NOT et les principaux symboles génériques.

J'ai donc pensé que c'était ça NOT IN, NOT EXISTSetc.

En ce qui concerne cette question SO , je pensais que la solution choisie par @GBN violerait la déclaration ci-dessus.

Apparemment, non.

Ma question est donc: pourquoi?

Stuart Blackler
la source

Réponses:

21
  • NOT IN (SELECT ...)et NOT EXISTS (SELECT .. WHERE correlation..)sont "Anti Semi Joins". Autrement dit, des opérations basées sur des ensembles reconnus

  • WHERE NOT (MyColumn = 1) est un filtre qui nécessite que toutes les lignes soient examinées

Pour plus d'informations, voir:

Modifier: pour être complet

Les JOINTS GAUCHES sont souvent moins performants. Voir http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server

Ce même site note que dans MySQL, NOT EXISTS n'est pas optimisé comme les autres SGBDR et LEFT JOIN est meilleur

Dans SQL Server, je sais par expérience que LEFT JOIN ne fonctionne pas aussi bien que NOT EXISTS. Vous avez également souvent besoin de DISTINCT pour obtenir les mêmes résultats qu'une autre étape de traitement.

gbn
la source
0

J'utilise une sous-sélection pour cela:

SELECT m* from Main AS m 
    WHERE m.id NOT IN 
        (SELECT m2.id FROM Main AS m2 
           WHERE m2.id IN (...possibly null/empty list goes here...));

Bien sûr, si votre table est grande, vous devrez analyser cela pour vérifier les performances. Si vous avez des clauses supplémentaires filtrant les résultats dans la requête principale, vous devrez peut-être les dupliquer dans la sous-sélection. Mais peu importe, la sous-sélection a un "IN" par rapport à un "NOT IN" et peut donc avoir des résultats de taille différente et, généralement, les performances des requêtes sont importantes, alors analysez cette approche lorsque vous l'utilisez avec une grande table.

adoucir
la source