2009-06-17 7 views
4

J'ai une situation où exécuter une requête filtrée par une colonne indexée dans une table partitionnée effectue une analyse de table complète.Comment utiliser un index sur une table partitionnée dans postgresql? 8.3.7

Apparemment, ceci est un problème connu dans postgresql, et il est expliqué en détail here.

Existe-t-il un moyen plus élégant de contourner cela que d'effectuer une requête sur chaque partition, puis d'effectuer une opération UNION sur tous les résultats?

+0

Veuillez également vous renseigner sur la liste de diffusion des performances de Postgres ici http://archives.postgresql.org/pgsql-performance/. –

+0

Cet article que vous liez est inexact, car l'auteur n'est pas très familier avec le partitionnement. Il n'a pas activé constraint_exclusion ou index sur chaque partition. –

+0

Je ne comprends pas pourquoi les index devraient être exclus juste parce qu'une requête croise les frontières de la partition. Dans mon cas, j'ai découvert ce problème lorsque j'essayais de trouver le très petit ensemble de valeurs distinctes pour une colonne qui a un index dans chaque partition. sélectionnez la colonne distincte sur la partition utilise l'analyse d'index. la même chose sur la table parent effectue un scan complet de chaque partition, puis fusionne, puis trie. "sélectionner une colonne distincte de (sélectionnez union select union select ...)" est WAY plus rapide que "select distinct column from parent" Quelqu'un at-il une idée de la raison pour laquelle le planificateur ne fait pas l'évidence? – ideasculptor

Répondre

10

Les index fonctionnent très bien pour analyser uniquement les partitions pertinentes dans PostgreSQL. Mais, vous devez tout configurer correctement pour que cela fonctionne, et il est facile de rater une étape dans la longue liste de choses documentées à http://www.postgresql.org/docs/current/static/ddl-partitioning.html

La principale chose à réaliser est que, afin d'éviter un balayage séquentiel, vous avoir à fournir suffisamment d'informations à PostgreSQL pour prouver que certaines partitions ne peuvent pas contenir les données que vous recherchez; ils sont ensuite ignorés en tant que sources potentielles pour les résultats de la requête. L'article que vous liez pointe comme une solution au problème d'analyse seq: "Si vous ajoutez des contraintes de plage au champ date de chaque partition, cette requête peut être optimisée dans une boucle où vous interrogez d'abord la partition" la plus récente ". en arrière jusqu'à ce que vous trouviez une seule valeur supérieure à celle de toutes les partitions restantes. "- mais ne montre pas le plan amélioré que vous verriez après ce changement.

Quelques erreurs courantes que vous avez fait:

-Le paramètre constraint_exclusion dans le fichier postgresql.conf est désactivé par défaut. Avec cette valeur par défaut, vous n'obtiendrez pas ce que vous attendez. -N'a pas créé de partitions sans chevauchement en utilisant CHECK, ce qui empêche le planificateur de savoir ce qu'il y a à l'intérieur de chacune d'entre elles. Il est possible de passer à côté de cette étape, mais vous obtenez toujours vos données correctement dans les bonnes partitions, le planificateur ne le saura tout simplement pas.

-N'a pas mis un index sur chaque partition, seulement créé un sur la table principale. Cela vous donnera un balayage séquentiel juste sur la partition pertinente, donc pas aussi mauvais que le dessus mais pas bon non plus. Il y a du travail pour rendre cela plus facile dans les prochaines versions de PostgreSQL (la configuration de constraint_partition est assez automatique dans 8.4 et une sorte d'automatisation de configuration de partition est en cours). À l'heure actuelle, si vous suivez attentivement les instructions et évitez tous ces problèmes, cela devrait fonctionner.

Questions connexes