Question

J'ai le tableau suivant:

id message_read notification_sent send_date           text                                                version recipient sender 
-- ------------ ----------------- ------------------- --------------------------------------------------- ------- --------- ------ 
1  true         false             2015-02-27 00:00:00 Bonjour. Je suis disponible pour la garde partagée. 0       2         3      
3  false        false             2015-03-01 00:00:00 Je suis disponible pour vous rencontrer dès demain. 0       2         3      
12 false        false             2015-02-27 00:00:00 Hello dude                                          0       2         1      

La requête ci-dessous est le type de requêtes que généralement exécuté sur ce tableau:

select * from public.message
where (recipient = 2 and sender = 3) or (sender = 2 and recipient = 3);

Je suis en train de créer des indices sur cette table et en gardant à l'esprit le genre de requêtes exécutées sur elle.

Voici mes indices:

CREATE INDEX recipient_idx ON message(recipient);
CREATE INDEX sender_idx ON message(sender);

et voici la sortie d'un explain analyze sur la requête ci-dessus:

QUERY PLAN                                                                                                                  
--------------------------------------------------------------------------------------------------------------------------  
Bitmap Heap Scan on message  (cost=8.57..13.40 rows=1 width=49) (actual time=0.072..0.075 rows=3 loops=1)                   
  Recheck Cond: ((sender = 3) OR (recipient = 3))                                                                           
  Filter: (((recipient = 2) AND (sender = 3)) OR ((sender = 2) AND (recipient = 3)))                                        
  Heap Blocks: exact=1                                                                                                      
  ->  BitmapOr  (cost=8.57..8.57 rows=2 width=0) (actual time=0.050..0.050 rows=0 loops=1)                                  
        ->  Bitmap Index Scan on sender_idx  (cost=0.00..4.28 rows=1 width=0) (actual time=0.037..0.037 rows=2 loops=1)     
              Index Cond: (sender = 3)                                                                                      
        ->  Bitmap Index Scan on recipient_idx  (cost=0.00..4.28 rows=1 width=0) (actual time=0.009..0.009 rows=1 loops=1)  
              Index Cond: (recipient = 3)                                                                                   
Planning time: 0.468 ms                                                                                                     
Execution time: 0.188 ms    

Quelqu'un peut-il me dire en quoi je suis arriver de mal?Pourquoi n'est-ce pas ma requête à l'aide d'un arbre d'index et une image bitmap à la place?Comment puis-je améliorer mes indices?

modifier:

Voici ce que j'ai essayé:

CREATE INDEX recipient_sender_idx ON message(recipient, sender);

L'exécution de l'expliquer, analyser maintenant les rendements:

QUERY PLAN                                                                                                                  
--------------------------------------------------------------------------------------------------------------------------  
Bitmap Heap Scan on message  (cost=8.57..13.40 rows=1 width=49) (actual time=0.035..0.038 rows=3 loops=1)                   
  Recheck Cond: ((sender = 3) OR (recipient = 3))                                                                           
  Filter: (((recipient = 2) AND (sender = 3)) OR ((sender = 2) AND (recipient = 3)))                                        
  Heap Blocks: exact=1                                                                                                      
  ->  BitmapOr  (cost=8.57..8.57 rows=2 width=0) (actual time=0.023..0.023 rows=0 loops=1)                                  
        ->  Bitmap Index Scan on sender_idx  (cost=0.00..4.28 rows=1 width=0) (actual time=0.015..0.015 rows=2 loops=1)     
              Index Cond: (sender = 3)                                                                                      
        ->  Bitmap Index Scan on recipient_idx  (cost=0.00..4.28 rows=1 width=0) (actual time=0.007..0.007 rows=1 loops=1)  
              Index Cond: (recipient = 3)                                                                                   
Planning time: 0.183 ms                                                                                                     
Execution time: 0.070 ms   

edit 2:

explain analyze
select * from public.message
where recipient = 2 and sender = 3 
UNION ALL
select * from public.message
where sender = 2 and recipient = 3

rendements:

QUERY PLAN                                                                                                                                     
---------------------------------------------------------------------------------------------------------------------------------------------  
Append  (cost=0.29..16.63 rows=2 width=49) (actual time=0.031..0.043 rows=3 loops=1)                                                           
  ->  Index Scan using recipient_sender_idx on message  (cost=0.29..8.31 rows=1 width=49) (actual time=0.030..0.031 rows=2 loops=1)            
        Index Cond: ((recipient = 2) AND (sender = 3))                                                                                         
  ->  Index Scan using recipient_sender_idx on message message_1  (cost=0.29..8.31 rows=1 width=49) (actual time=0.009..0.010 rows=1 loops=1)  
        Index Cond: ((recipient = 3) AND (sender = 2))                                                                                         
Planning time: 0.389 ms                                                                                                                        
Execution time: 0.075 ms                                                                                                  

mais il n'est pas possible de modifier ma requête SQL.

Était-ce utile?

La solution

Je pense que la raison c'est la cueillette de l'unique index et le joint torique est que vos données sont-jouet de taille moyenne;témoignage:

  ->  BitmapOr  (rows=0 loops=1)                                  
        ->  Bitmap Index Scan on sender_idx  (rows=2 loops=1)     
              Index Cond: (sender = 3)                                                                                      
        ->  Bitmap Index Scan on recipient_idx  (rows=1 loops=1)  
              Index Cond: (recipient = 3)    

et

    scanned 101 of 101 pages, containing 9642 live rows

La table est assez petit et les indices sont très sélectifs, il est donc probablement plus rapide pour numériser les plus petits index puis filtrer les résultats.Il n'y a pas de point à l'aide d'un indice composite lorsque le singulier indices de trouver juste un couple de lignes, de toute façon.


Si les données ont été plus grands et/ou il n'y avait plus de lignes pour un expéditeur/destinataire, idéalement, il devrait utiliser deux indépendants des analyses à index sur un indice composite, puis de les fusionner.Je ne pense pas que le planificateur est assez intelligent pour se rendre compte que ce peut être exécutée que les deux requêtes et UNIONed,cependant, de sorte que le meilleur que vous allez obtenir est probablement deux bitmap index des analyses sur l'indice composite, puis un BitmapOr.

Essayez:

select * from public.message
where recipient = 2 and sender = 3 
UNION ALL
select * from public.message
sender = 2 and recipient = 3;

pour savoir si le plan choisi est plus proche de ce que vous voulez.Même si elle produit le plan que vous voulez, avec deux IndexScan nœuds sur l'indice composite puis Ajouter un nœud à l'union, il pourrait en fait être plus lent.

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top