2010-12-10 23 views
2

Vous avez cette ici question:« splain un postgresql me expliquiez

EXPLAIN 
SELECT persons.id AS id, ppm.first 
FROM myschema.persons 
INNER JOIN myotherschema.ppm ON persons.key = ppm.pid 
WHERE persons.id = 279759; 

La colonne ppm.pid est une clé primaire et dans l'indice:

CREATE INDEX ppm_pkey_index 
    ON myotherschema.ppm 
    USING btree 
    (pid); 

Et voici la EXPLIQUER:

Hash Join (cost=8.31..3105.40 rows=306 width=23) 
    Hash Cond: (textin(int4out(ppm.pid)) = persons.key) 
    -> Seq Scan on ppm (cost=0.00..2711.33 rows=61233 width=23) 
    -> Hash (cost=8.29..8.29 rows=1 width=12) 
     -> Index Scan using pskey on persons (cost=0.00..8.29 rows=1 width=12) 
       Index Cond: (id = 279759) 

Il ne semble pas utiliser le ppm_pkey_index du tout: il semble toujours scanner 61,233 lignes Pourquoi est-ce? Est-ce que je le mal interprète? Corollaire: les clés primaires ne sont-elles pas automatiquement indexées dans postgresql? Mon index est-il redondant?

+7

Sauf si vous vous appelez Ricky Riccardo, vous devriez éviter mot "'splain". (Dieu je suis vieux.) –

+0

Je n'ai pas besoin de "diviniser à vous comme pourquoi" splain est tellement génial. – Wells

Répondre

2

clés primaires créent clés UNIQUE sur votre clé. Votre index est donc redondant.

Avez-vous exécuté vacuum analyze sur votre table après en créant l'index?

sql> vacuum analyze myotherschema.ppm; 

Je vois un autre problème maintenant: sont ppm.pid et persons.key du même type de terrain? Vous pouvez rencontrer perfomance problèmes en raison de conversions de données inutiles, et l'impossibilité d'utiliser les index parce que vous n'indexez pas sur les fonctions de diffusion que vous devez utiliser sur la jointure ...

+0

Désolé-collé le mauvais index là-bas. Je l'ai mis à jour maintenant. – Wells

+0

Ah oui, persons.key est varchar, pid un entier. Serait-il sensé de changer la jointure de la requête en "ON persons.key :: integer = ppm.pid"? Je ne peux pas changer de type, malheureusement. – Wells

+0

Cela a fonctionné! J'ai explicitement casté key :: integer et l'analyse est partie. Merci! – Wells

0

Qu'est-ce qui se passe si vous changez à:

EXPLAIN 
SELECT persons.id AS id, ppm.first 
FROM myschema.persons 
INNER JOIN myotherschema.ppm ON persons.id = 279759 
AND persons.key = ppm.pid; 
+0

Certes, postgres a un optimiseur de requête qui est assez intelligent pour connaître l'itinéraire le plus rapide, peu importe comment vous l'écrivez? – Langdon

+0

Peut-être que l'optimiseur de requête ne peut pas être si intelligent lorsque la requête traverse des schémas? –

+0

@ Paul Tomblin: optimiseur n'a aucun problème avec les tables étant dans différents schémas ou tablespaces. –