2009-12-03 3 views
1

J'ai deux tables:Postgresql 8.3, simple requête de ne pas utiliser l'index

table1 (about 200000 records) 
number varchar(8) 

table2 (about 2000000 records) 
number varchar(8) 

'nombre' champs dans les deux tables ont des index standard. Pour chaque enregistrement de la table 1, environ 10 enregistrements de la table 2 sont affectés.

J'exécute la requête:

explain select table1.number from table1, table2 where table1.number = table2.number; 

Le plan de requête indique que les index ne seront pas utilisés, Scans Seq partout;)

Mais si je réduis nombre d'enregistrements dans le tableau 1 à ~ 2000 plan de requête commence à montrer que l'index sera utilisé. Peut-être que quelqu'un peut me dire pourquoi postgresql se comporte de cette façon?

Répondre

-1

Cela peut dépendre de la façon dont vos index ont été créés. Si "nombre" est en fait un nombre, vous devriez penser à changer le type de colonne en bigint. Encore une fois, pas sûr à 100%, mais je pense que l'indexation sur les colonnes de caractères fonctionne différemment que sur les champs numériques ... Je pourrais cependant parler de mes fesses.

+1

En raison de décisions de conception passées, il ne s'agit pas toujours d'un nombre –

2

Oui, le PostgreSQL docs peut vous le dire!

Voici quelques faits saillants:

Lorsque les index ne sont pas utilisés, il peut être utile pour tester pour forcer leur utilisation. Il existe des paramètres d'exécution qui peuvent désactiver différents types de plan (voir Section 18.6.1). Par exemple, en désactivant des analyses séquentielles (enable_seqscan) et des jointures en boucle imbriquées (enable_nestloop), qui sont les plans de base les plus , forcez le système à d'utiliser un plan différent. Si le système choisit toujours un balayage séquentiel ou une jointure de boucle imbriquée alors il y a probablement une raison plus fondamentale pour laquelle l'index n'est pas utilisé; pour par exemple, la condition de requête ne correspond pas à l'index. (Quel type de requête peut utiliser ce type d'indice est expliqué dans les sections précédentes.)

Si forcer l'utilisation d'index n'utilise l'indice , alors il y a deux possibilités: Soit le système est droit et l'utilisation l'index est en effet ne convient pas, ou les estimations de coûts des plans de requête ne reflètent pas réalité. Donc, vous devriez chronométrer votre requête avec et sans index. La commande EXPLAIN ANALYZE peut être utile ici.

4

Les analyses séquentielles sont normales (et optimales) pour les requêtes avec une très faible sélectivité, c'est-à-dire pour les requêtes qui traversent des tables entières. Lorsque vous supprimiez la plupart des lignes de la table 1, il ne couvrait plus toutes les valeurs distinctes possibles de table2 - c'est pourquoi l'analyse d'index est venue à l'utilisation.

Pour commencer, je vous recommande d'essayer cette requête:

select * from pg_stats where tablename in ('table1','table2'); 

C'est l'information que PostgreSQL utilise pour construire un plan de requête. Le planificateur lui-même est assez compliqué - consultez les documents (mentionnés par Jonathan) et les sources [http://doxygen.postgresql.org/ -> src/backend/optimizer] si vous êtes si curieux.

+0

+1 Tout dépend de la cardinalité des valeurs. – Trey

Questions connexes