CLUSTER
Si vous avez l'intention d'utiliser CLUSTER
, la syntaxe affichée n'est pas valide.
create CLUSTER ticket USING ticket_1_idx;
Exécuter une fois :
CLUSTER ticket USING ticket_1_idx;
Cela peut aide beaucoup avec de plus grands ensembles de résultats. Pas tellement pour une seule ligne renvoyée.
Postgres se souvient de l'index à utiliser pour les appels suivants. Si votre tableau n'est pas en lecture seule, l'effet se détériore avec le temps et vous devez le réexécuter à certains intervalles :
CLUSTER ticket;
Peut-être uniquement sur des partitions volatiles. Voir ci-dessous.
Cependant , si vous avez beaucoup de mises à jour, CLUSTER
(ou VACUUM FULL
) peut en fait être mauvais pour les performances. La bonne quantité de ballonnement permet UPDATE
pour placer de nouvelles versions de lignes sur la même page de données et évite d'avoir à étendre trop souvent physiquement le fichier sous-jacent dans le système d'exploitation. Vous pouvez utiliser un FILLFACTOR
soigneusement réglé pour obtenir le meilleur des deux mondes :
- Facteur de remplissage pour un index séquentiel qui est PK
pg_repack
CLUSTER
prend un verrou exclusif sur la table, ce qui peut être un problème dans un environnement multi-utilisateurs. Citant le manuel :
Lorsqu'une table est mise en cluster, un
ACCESS EXCLUSIVE
le verrou est acquis sur celui-ci. Cela empêche toute autre opération de base de données (à la fois lecture et écriture ) d'opérer sur la table jusqu'auCLUSTER
est terminé.
Bold emphase mienne. Envisagez l'alternative pg_repack
:
Contrairement à
CLUSTER
etVACUUM FULL
il fonctionne en ligne, sans détenir un verrou exclusif sur les tables traitées pendant le traitement. pg_repack est efficace pour démarrer, avec des performances comparables à l'utilisation deCLUSTER
directement.
et :
pg_repack doit prendre un verrou exclusif à la fin de la réorganisation.
La version 1.3.1 fonctionne avec :
PostgreSQL 8.3, 8.4, 9.0, 9.1, 9.2, 9.3, 9.4
La version 1.4.2 fonctionne avec :
PostgreSQL 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 10
Requête
La requête est suffisamment simple pour ne pas causer de problèmes de performances en soi.
Cependant, un mot sur l'exactitude :Le BETWEEN
construire inclut les frontières. Votre requête sélectionne tout le 19 décembre plus enregistrements du 20 décembre à 00h00. C'est extrêmement improbable exigence. Il y a de fortes chances que vous vouliez vraiment :
SELECT *
FROM ticket
WHERE created >= '2012-12-19 0:0'
AND created < '2012-12-20 0:0';
Performances
Tout d'abord, vous demandez :
Pourquoi sélectionne-t-il l'analyse séquentielle ?
Votre EXPLAIN
la sortie montre clairement un balayage d'index , pas une analyse de table séquentielle. Il doit y avoir une sorte de malentendu.
Si vous êtes pressé pour de meilleures performances, vous pourrez peut-être améliorer les choses. Mais les informations de base nécessaires ne sont pas dans la question. Les options possibles incluent :
-
Vous ne pouvez interroger que les colonnes requises au lieu de
*
pour réduire les coûts de transfert (et éventuellement d'autres avantages en termes de performances). -
Vous pourriez regarder le partitionnement et placez des tranches de temps pratiques dans des tables séparées. Ajoutez des index aux partitions si nécessaire.
-
Si le partitionnement n'est pas une option, une autre technique connexe mais moins intrusive consisterait à ajouter un ou plusieurs index partiels .
Par exemple, si vous interrogez principalement le mois en cours , vous pouvez créer l'index partiel suivant :CREATE INDEX ticket_created_idx ON ticket(created) WHERE created >= '2012-12-01 00:00:00'::timestamp;
CREATE
un nouvel index juste avant le début d'un nouveau mois. Vous pouvez facilement automatiser la tâche avec une tâche cron.FacultativementDROP
index partiels pour les anciens mois plus tard. -
Conserver l'index total en plus pour
CLUSTER
(qui ne peut pas fonctionner sur des index partiels). Si les anciens enregistrements ne changent jamais, le partitionnement de table aiderait beaucoup cette tâche, car vous n'avez qu'à regrouper les nouvelles partitions. Là encore, si les enregistrements ne changent jamais du tout, vous n'avez probablement pas besoin deCLUSTER
.
Si vous combinez les deux dernières étapes, les performances devraient être impressionnantes.
Bases sur les performances
Il vous manque peut-être une des bases. Tous les conseils de performance habituels s'appliquent :
- https://wiki.postgresql.org/wiki/Slow_Query_Questions
- https://wiki.postgresql.org/wiki/Performance_Optimization