J'ai lu ce livre qui dit que
La base de données suppose que Indexed_Col IS NOT NULL couvre une plage trop grande pour être utile, de sorte que la base de données ne conduira pas à un index à partir de cette condition.
Je reconnais que le livre a plus de 10 ans, mais il s'est déjà avéré très utile - En utilisant les instructions glanées dans ses pages, j'ai accéléré une requête d'un facteur dix.
De plus, en exécutant EXPLAIN ANALYZE
une SELECT
requête, j'ai constaté qu'aucun de mes index n'est utilisé, même si, par tous les droits, il devrait l'être.
Ainsi, ma question est:
En supposant qu'il existe une table qui a une colonne, dont la définition de colonne inclut "NOT NULL", et qu'il existe un index qui couvre cette colonne, cet index serait-il utilisé dans une requête de cette table où les colonnes font partie de la requête?
Comme:
CREATE TABLE my_table(
a varchar NOT NULL
);
CREATE INDEX ix_my_table ON my_table(a);
SELECT a from my_table;
la source
WHERE column IS NOT NULL
peut ne pas utiliser l'index car, comme le dit le livre: "couvre une plage trop grande pour être utile". Si 90% des valeurs ne sont pas nulles, un seqscan sera probablement plus rapide aussi.NOT NULL
colonne pour uneIS NOT NULL
requête, à moins que cet index ne soit également utile pour d'autres parties de laWHERE
clause, les filtres de jointure, etc., ou qu'il soit utilisable pour une analyse ordonnée uniquement par index. En d'autres termes, il ignorera complètement le redondantIS NOT NULL
sur laNOT NULL
colonne et fera des choix d'utilisation d'index en fonction d'autres détails. (Voir éditer, re analyses uniquement indexées).En plus de la réponse complète de Craig, je voulais ajouter que la couverture du livre auquel vous faites référence dit:
Je ne lui ferais donc pas confiance pour être une excellente source de conseils sur PostgreSQL en particulier. Chaque SGBDR peut être étonnamment différent!
Je suis un peu confus au sujet de votre question d'origine, mais voici un exemple montrant que la section du livre n'est pas correcte à 100%. Pour éviter toute confusion, voici l'intégralité du paragraphe pertinent, vous pouvez le voir dans Google Recherche de Livres .
Postgres peut réellement (dans le cas artificiel suivant) utiliser un index pour satisfaire les
IS NOT NULL
requêtes sans ajouter de contraintes de balayage de plage comme suggéréPositive_ID_Column > -1
. Voir les commentaires sur les questions de Craig pour savoir pourquoi Postgres choisit cet index dans ce cas particulier, et la note sur l'utilisation des index partiels.Il s'agit en fait de Postgres 9.3, mais je pense que les résultats seraient à peu près similaires sur 9.1, bien qu'il n'utilise pas de "Index Only Scan".
Edit: Je vois que vous avez clarifié votre question d'origine, et vous vous demandez apparemment pourquoi Postgres n'utilise pas d'index dans un exemple simple comme:
Probablement parce que vous n'avez aucune ligne dans le tableau. Ajoutez donc des données de test et
ANALYZE my_table;
.la source
NOT NULL
, et non que la requête utiliseIS NOT NULL
comme condition d'index. C'est dans les commentaires que vous avez référencés, mais je mettrai à jour la question pour l'inclure.Vous n'avez pas publié votre requête ou exemple de données. Mais la raison la plus courante pour laquelle les index ne sont pas utilisés est le volume.
Les index sont comme un annuaire téléphonique qui traduit une colonne en un emplacement de ligne. Si vous ne recherchez que quelques lignes, il est logique de rechercher chaque ligne du répertoire, puis de rechercher la ligne dans le tableau principal.
Mais pour plus de quelques lignes, il est moins cher d'ignorer le répertoire téléphonique et d'itérer sur toutes les lignes de la table principale. D'après mon expérience, le point de basculement est d'environ 100 lignes.
la source
CREATE INDEX ix_frank ON people(name) WHERE name ='frank'
.NOT NULL