Exemple très simple - une table, un index, une requête:
CREATE TABLE book
(
id bigserial NOT NULL,
"year" integer,
-- other columns...
);
CREATE INDEX book_year_idx ON book (year)
EXPLAIN
SELECT *
FROM book b
WHERE b.year > 2009
donne moi:
Seq Scan on book b (cost=0.00..25663.80 rows=105425 width=622)
Filter: (year > 2009)
Pourquoi ne PAS effectuer une analyse d'index à la place? Qu'est-ce que je rate?
Si SELECT renvoie plus de 5 à 10% environ de toutes les lignes de la table, une analyse séquentielle est beaucoup plus rapide qu'une analyse d'index.
En effet, une analyse d'index nécessite plusieurs IO opérations pour chaque ligne (recherchez la ligne dans l'index, puis extrayez-la du tas). Alors qu'une analyse séquentielle ne nécessite qu'un seul IO pour chaque ligne, voire moins, car un bloc (page) sur le disque contient plus d'une ligne, il est donc possible d'extraire plusieurs lignes avec un seul IO opération.
Btw: cela est également vrai pour les autres SGBD. Certaines optimisations sous "Analyses uniquement indexées" sont mises de côté (mais pour un SELECT *, il est fort peu probable qu'un tel SGBD opterait pour une "analyse uniquement indexée")
Avez-vous ANALYSÉ la table/la base de données? Et que dire de la statistiques ? Lorsqu'il existe de nombreux enregistrements dont l'année> 2009, une analyse séquentielle peut être plus rapide qu'une analyse d'index.
Dans le balayage d'index, la tête de lecture saute d'une ligne à l'autre, ce qui est 1000 fois plus lente que la lecture du bloc physique suivant (dans le balayage séquentiel).
Ainsi, si (le nombre d'enregistrements à récupérer * 1 000) est inférieur au nombre total d'enregistrements, l'analyse d'index fonctionnera mieux.