Impact de CLUSTER sur les performances

8

J'essaie d'optimiser ma base de données Postgres 9.2 pour accélérer les requêtes avec des restrictions de date.

J'ai une timestampcolonne, mais la plupart du temps je demande un jour, donc j'ai créé un index avec timestampà l' dateanalyse syntaxique:

CREATE INDEX foo_my_timestamp_idx
ON foo
USING btree
((my_timestamp::date) DESC);

Maintenant, pour augmenter une CLUSTER footable de performances I en utilisant l'index ci-dessus:

CLUSTER foo USING foo_my_timestamp_idx;

Selon le manuel sur SQL-CLUSTER , le tableau

est réorganisé physiquement sur la base des informations d'index

Je me demande s'il y a un impact sur les performances pour d'autres requêtes utilisant un PK de table (disons id_foo). Y a-t-il des inconvénients?

ilovkatie
la source

Réponses:

10

Oui, il peut y avoir des inconvénients. Si une autre requête examine un segment de données différent non déterminé par la date, les performances peuvent être affectées si les lignes sont désormais réparties sur plusieurs pages de données. De la même manière que vos bénéfices de première requête. Cela dépend complètement des informations qui ne sont pas dans votre question.

d'autres requêtes utilisant un PK de table (disons id_foo)

Ça pourrait être n'importe quoi . Cela dépend de ce que vous avez et de ce que vous interrogez exactement . L'interrogation d'une seule ligne n'est pas affectée dans les deux cas, mais plusieurs lignes peuvent l'être.

Sachez que CLUSTERréécrit la table en parfait état comme le VACUUM FULLfait (supprime les tuples morts, compacte la taille physique de la table, réécrit les index). Vous pouvez donc voir un effet positif immédiat sur les performances de lecture indépendamment de l'ordre de tri. (Tout comme vous le feriez avec VACUUM FULL.)
Après CLUSTER, vous souhaiterez peut-être également exécuter un simple VACUUMsur la table pour mettre à jour la carte de visibilité - ce qui peut permettre des analyses d'index uniquement.

Tous les avantages du CLUSTERrétrécissement avec la fréquence d'écriture.

De plus, si vous avez de nombreuses mises à jour du tableau, cela CLUSTERpeut en fait nuire aux performances d'écriture en supprimant la "marge de manœuvre" pour les mises à jour CHAUDES sur la même page de données. Vous pourriez être en mesure de contrer cet effet avec un FILLFACTORparamètre inférieur à 100. Encore une fois, cela dépend de la localité des lignes mises à jour, etc.

En relation:

Quoi qu'il en soit, je ne ferais probablement pas d' indexation et de cluster my_timestamp::date, mais my_timestampdirectement. Rien de perdu, quelque chose de gagné. Le casting est très bon marché, mais il est toujours moins cher de ne pas lancer du tout. Et l'index peut prendre en charge plus de requêtes.

CREATE INDEX foo_my_timestamp_idx ON foo (my_timestamp);

Même si un daten'occupe que 4 octets sur le disque et un timestampoccupe 8 octets, la différence est généralement perdue par le remplissage d'alignement pour votre cas, et les deux index ont exactement la même taille.

L'ordre de plusieurs lignes le même jour résultant de votre index d'expression est arbitraire. Il peut toujours y avoir deux horodatages identiques, mais avec 6 chiffres fractionnaires, ce qui est normalement très improbable. En plus de cela, vous obtenez un ordre déterministe de lignes, ce qui peut présenter divers avantages.

J'ai également laissé tomber le DESCmot clé car Postgres peut lire les index vers l'arrière pratiquement aussi rapidement que vers l'avant. (Cependant, l'ordre de tri est important pour les index multicolonnes!) Plus:

Au lieu de:

SELECT * FROM foo
WHERE my_timestamp::date = '2016-07-25';

Vous utiliseriez maintenant:

SELECT * FROM foo
WHERE  my_timestamp >= '2016-07-25'  -- this is a timestamp literal now
WHERE  my_timestamp <  '2016-07-26';

Même performance.

Si vous n'avez pas besoin du composant de temps de la colonne du tout , convertir la colonne date...

Comment revenir en arrière CLUSTER?

CLUSTERsur une seule table peut être annulée avec ROLLBACKcomme n'importe quelle autre commande régulière tant que la transaction n'a pas été validée.

Cependant, je cite le manuel :

CLUSTERsans aucun paramètre, reclasse toutes les tables précédemment groupées dans la base de données actuelle que l'utilisateur appelant possède, ou toutes ces tables si elles sont appelées par un superutilisateur. Cette forme de CLUSTERne peut pas être exécutée à l'intérieur d'un bloc de transaction.

Vous pouvez toujours exécuter CLUSTERavec un index différent pour modifier à nouveau l'ordre physique des lignes.

Erwin Brandstetter
la source
Awsome réponse, j'ai besoin de demander alors, comment «annuler» CLUSTER? Dois-je CLUSTERutiliser un PK maintenant?
ilovkatie
@ilovkatie: J'ai ajouté un peu comment revenir en arrière.
Erwin Brandstetter