Vous n'êtes pas identifié(e).
Pages : 1
Bonjour,
Je fais face à un problème très étrange.
En regardant le plan d'exécution d'une requête, celui-ci diffère selon les valeurs que je passe au WHERE.
La requête :
explain analyze
select
session_id
from
session
where
id = XXXX and
session_id between 300100000 and 303204368
Lorsqu'id = 9214 :
QUERY PLAN
Index Scan using session_id_idx on session (cost=0.00..91050.10 rows=5848 width=4) (actual time=0.797..324.467 rows=207 loops=1)
Index Cond: ((session_id >= 300100000) AND (session_id <= 303204368) AND (id = 9214))
Total runtime: 324.532 ms
Lorsqu'id = 8131 :
QUERY PLAN
Bitmap Heap Scan on session (cost=60380.26..62442.27 rows=517 width=4) (actual time=60816.526..60816.558 rows=4 loops=1)
Recheck Cond: ((id = 8131) AND (session_id >= 300100000) AND (session_id <= 303204368))
-> BitmapAnd (cost=60380.26..60380.26 rows=517 width=0) (actual time=60816.392..60816.392 rows=0 loops=1)
-> Bitmap Index Scan id_idx (cost=0.00..1015.53 rows=53243 width=0) (actual time=0.128..0.128 rows=325 loops=1)
Index Cond: (id = 8131)
-> Bitmap Index Scan on pk_t_session_sin (cost=0.00..59364.22 rows=2829602 width=0) (actual time=60814.642..60814.642 rows=3103959 loops=1)
Index Cond: ((session_id >= 300100000) AND (session_id <= 303204368))
Total runtime: 60816.602 ms
Je précise qu'il existe un indexe sur id et sur (session_id,id).
Je ne comprend donc pas pourquoi les plans d'exécution sont différents.
Merci d'avance pour vos réponses,
Christophe
Dernière modification par cbernard (15/10/2010 09:17:06)
Hors ligne
Bonjour,
C'est «normal». Il prend en compte le nombre d'enregistrements ramenés par les différents éléments de la clause where, afin d'essayer de déterminer le meilleur plan d'exécution. Suivant les valeurs d'id, il estime différemment le nombre d'enregistrements ramenés par la requête, et choisit un plan différent.
Le vrai problème, c'est que votre index n'est pas 'dans le bon sens' pour la requête: il devrait être sur (id, session_id), puisque vous demandez une valeur précise d'id et une plage de valeurs pour session_id (c'est du à la structure des index btree composés sur plusieurs colonnes).
Autre problème: je ne comprends pas pourquoi il faut 60 secondes à la base pour parcourir pk_t_session_sin. L'index doit être très fragmenté, et devrait probablement être reconstruit (REINDEX). À moins que votre machine ne soit réellement très lente (disques durs lents), et que la première requête ait bénéficié du cache, et pas la seconde.
Marc.
Hors ligne
Bonjour,
Et merci pour les explications, notamment sur le "sens" de l'index, je n'avais pas saisi que l'ordre avait un impact sur le plan d'exécution.
Je vais donc recréer un nouvel index et par la même occasion reindexer pk_t_session car les disques sont rapides (SAS 15k)
Je referai une analyse par la suite.
Christophe
Hors ligne
Vous pouvez aussi jouer avec le paramètre random_page_cost (en l'abaissant) pour favoriser l'utilisation des index.
Guillaume.
Hors ligne
Merci pour le commentaire, j'avais effectivement changé random_page_cost à 2.0 et noté un gain d'environ 20% sur l'EXPLAIN.
Christophe
Hors ligne
Pages : 1