Comment puis-je la force de Postgres pour l'utilisation d'un index particulier?
Comment puis-je la force de Postgres pour utiliser un index quand elle aurait par ailleurs insister sur le fait de faire un balayage séquentiel?
- Dupliqué, voir stackoverflow.com/questions/14554302/...
Vous devez vous connecter pour publier un commentaire.
En supposant que vous vous posez sur la commune d'index "allusion" fonctionnalité que l'on trouve dans de nombreuses bases de données PostgreSQL ne fournit pas cette fonctionnalité. C'était une décision consciente par l'PostgreSQL équipe. Un bon aperçu de pourquoi et ce que vous pouvez faire, en revanche, peut être trouvé ici. Les raisons sont essentiellement, que c'est une performance hack qui a tendance à causer plus de problèmes par la suite que vos modifications de données, alors que PostgreSQL est optimizer pouvez ré-évaluer le plan basé sur les statistiques. En d'autres termes, ce qui pourrait être un bon plan de requête d'aujourd'hui ne sera probablement pas un bon plan de requête pour tous les temps, et les indicateurs d'index de la force particulière de plan de requête pour tous les temps.
Comme un très émoussé marteau, utile pour les tests, vous pouvez utiliser le
enable_seqscan
etenable_indexscan
paramètres. Voir:enable_
paramètresCe sont pas adapté pour la production en cours d'utilisation. Si vous avez des problèmes avec le plan de requête choix, vous devriez voir la documentation pour le suivi des problèmes de performances des requêtes. Ne pas juste mettre
enable_
params et à pied.Sauf si vous avez une très bonne raison pour l'utilisation de l'index, Postgres peut-être faire le bon choix. Pourquoi?
Voir aussi ce vieux message de groupe de discussion.
Probablement la seule raison valable pour l'utilisation de
c'est quand vous êtes de l'écriture de requêtes et que vous voulez rapidement voir ce que le plan de requête serait en réalité ont été il y de grandes quantités de données dans la table(s). Ou bien sûr, si vous avez besoin rapidement de confirmer que votre requête n'est pas à l'aide d'un indice tout simplement parce que le jeu de données est trop petit.
set enable_seqscan=false
, l'exécution de votre requête, puis exécuter rapidementset enable_seqscan=true
de retour postgresql pour son bon comportement (et, évidemment, ne le faites pas dans la production, que dans le développement!)Parfois PostgreSQL ne parvient pas à faire le meilleur choix d'index pour une condition particulière. Supposons, par exemple, il y a une table des transactions avec plusieurs millions de lignes, dont il existe plusieurs centaines pour un jour donné, et la table a quatre indices: l'identificateur de la transaction, client_id, la date et la description. Vous souhaitez exécuter la requête suivante:
PostgreSQL peut choisir d'utiliser l'index transactions_description_idx au lieu de transactions_date_idx, ce qui peut conduire à la requête de prendre quelques minutes au lieu de moins d'une seconde. Si c'est le cas, vous pouvez forcer l'utilisation de l'indice sur la date par fausser la condition comme ceci:
your_wanted_index
, il peut en être ainsi que postgresql moteur, il suffit de faire une séquence / clé primaire de numérisation à la place. Conclusion - il n'est pas fiable à 100% méthode pour forcer certains de l'utilisation des index pour le serveur PostgreSql.La question sur lui-même est très bien non valide. Forcer (en faisant enable_seqscan=off par exemple) est de très mauvaise idée. Il pourrait être utile de vérifier si elle sera plus rapide, mais le code de production ne devrait jamais utiliser de tels trucs.
Au lieu - expliquez-analyse de votre requête, le lire, et de savoir pourquoi PostgreSQL choisit le mauvais (à votre avis) plan de.
Il existe des outils sur le web qui aident à la lecture explain analyze de sortie de l'un d'eux est explain.depesz.com - écrit par moi.
Une autre option est de rejoindre #postgresql canal sur freenode réseau irc, et de parler à des gars là pour vous aider - comme l'optimisation de requête n'est pas une question de "poser une question, obtenir une réponse à être heureux". c'est plus comme une conversation, avec beaucoup de choses à vérifier, beaucoup de choses à apprendre.
Réponse courte
Ce problème se produit généralement lorsque le coût estimé d'un index scan est trop élevé et de ne pas refléter correctement la réalité. Vous devrez peut-être baisser le
random_page_cost
paramètre de configuration pour résoudre ce problème. À partir de la Postgres documentation:Vous pouvez vérifier si une valeur inférieure seront effectivement rendre Postgres utiliser l'index (mais l'utiliser pour test):
Vous pouvez rétablir la valeur par défaut avec
SET random_page_cost = DEFAULT;
de nouveau.Fond
Analyses à Index non-séquentielle disque page extrait. Postgres utilise
random_page_cost
pour estimer le coût de la non-séquentielle des extractions par rapport à des extractions séquentielles. La valeur par défaut est4.0
, assumant ainsi une moyenne coût du facteur 4 par rapport aux extractions séquentielles (mise en cache de la prise en compte les effets).Le problème, toutefois, est que cette valeur par défaut est inapte à la suite d'une importante scénarios réels:
1) disques à l'état Solide
Selon cette diapositive à partir d'un parler à PostgresConf 2018,
random_page_cost
doit être réglé à2.0
ou plus faible pour les disques à l'état solide.2) sont Largement à la mise en cache des données
Si vous savez que l'indice est entièrement mis en cache dans la RAM (vous pouvez aussi utiliser le pg_prewarm extension pour cela),
random_page_cost
devrait même être mis à1.0
.Il y a un truc pour pousser postgres à préférer un seqscan l'ajout d'un
OFFSET 0
dans la sous-requêteC'est pratique pour l'optimisation de requêtes reliant grand/énorme tables lorsque tous vous avez besoin est seulement à la n de poing/le dernier élément.
Permet de dire que vous êtes à la recherche pour le premier/dernier 20 éléments impliquant plusieurs tables ayant 100k (ou plus) de participants, aucun point de la construction et de raccordement de toutes les requêtes sur toutes les données lors de ce que vous allez être à la recherche pour est dans le premier de 100 ou de 1000 entrées. Dans ce scénario, par exemple, il s'avère être plus de 10 fois plus rapide de faire un balayage séquentiel.
voir Comment puis-je empêcher Postgres de l'in-lining, une sous-requête?
EnterpriseDB PostgresPlus Advanced Server produit prend en charge Oracle conseils de syntaxe, bien que le produit n'est pas libre.