CLUSTER
Hvis du har til hensigt at bruge CLUSTER
, den viste syntaks er ugyldig.
create CLUSTER ticket USING ticket_1_idx;
Kør én gang:
CLUSTER ticket USING ticket_1_idx;
Dette kan hjælpe meget med større resultatsæt. Ikke så meget for en enkelt række returneret.
Postgres husker hvilket indeks der skal bruges til efterfølgende opkald. Hvis din tabel ikke er skrivebeskyttet, forværres effekten over tid, og du skal køre igen med visse intervaller:
CLUSTER ticket;
Muligvis kun på flygtige partitioner. Se nedenfor.
Men , hvis du har mange opdateringer, CLUSTER
(eller VACUUM FULL
) kan faktisk være dårligt for ydeevnen. Den rigtige mængde oppustethed tillader UPDATE
at placere nye rækkeversioner på den samme dataside og undgår behovet for fysisk at udvide den underliggende fil i OS for ofte. Du kan bruge en omhyggeligt indstillet FILLFACTOR
for at få det bedste fra begge verdener:
- Fyldfaktor for et sekventielt indeks, der er PK
pg_repack
CLUSTER
tager en eksklusiv lås på bordet, hvilket kan være et problem i et flerbrugermiljø. Citerer manualen:
Når en tabel klynges, vises en ACCESS EXCLUSIVE
lås er erhvervet på det. Dette forhindrer andre databaseoperationer (både læser og skriver ) fra at arbejde på bordet indtil CLUSTER
er færdig.
Fed understregning min. Overvej alternativet pg_repack
:
I modsætning til CLUSTER
og VACUUM FULL
det fungerer online uden at holde en eksklusiv lås på de behandlede tabeller under behandlingen. pg_repack er effektiv at starte op, med ydeevne, der kan sammenlignes med at bruge CLUSTER
direkte.
og:
pg_repack skal tage en eksklusiv lås i slutningen af omorganiseringen.
Version 1.3.1 fungerer med:
PostgreSQL 8.3, 8.4, 9.0, 9.1, 9.2, 9.3, 9.4
Version 1.4.2 fungerer med:
PostgreSQL 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 10
Forespørgsel
Forespørgslen er enkel nok til ikke at forårsage nogen præstationsproblemer i sig selv.
Dog et ord om korrekthed :BETWEEN
konstruktion inkluderer grænser. Din forespørgsel vælger hele 19. december plus optegnelser fra 20. december kl. 00:00. Det er ekstremt usandsynligt krav. Chancerne er, at du virkelig ønsker:
SELECT *
FROM ticket
WHERE created >= '2012-12-19 0:0'
AND created < '2012-12-20 0:0';
Ydeevne
Først og fremmest spørger du:
Hvorfor vælger den sekventiel scanning?
Din EXPLAIN
output viser tydeligt en indeksscanning , ikke en sekventiel tabelscanning. Der må være en form for misforståelse.
Hvis du bliver presset hårdt for bedre ydeevne, kan du muligvis forbedre tingene. Men den nødvendige baggrundsinformation er ikke i spørgsmålet. Mulige muligheder omfatter:
-
Du kunne kun forespørge påkrævede kolonner i stedet for
*
for at reducere overførselsomkostninger (og muligvis andre præstationsfordele). -
Du kunne se på partitionering og læg praktiske tidsskiver i separate tabeller. Tilføj indekser til partitioner efter behov.
-
Hvis partitionering ikke er en mulighed, ville en anden relateret, men mindre påtrængende teknik være at tilføje et eller flere delvise indekser .
For eksempel, hvis du for det meste forespørger på den aktuelle måned , kan du oprette følgende delvise indeks:CREATE INDEX ticket_created_idx ON ticket(created) WHERE created >= '2012-12-01 00:00:00'::timestamp;
CREATE
et nyt indeks lige før starten på en ny måned. Du kan nemt automatisere opgaven med et cron-job. ValgfritDROP
delvise indekser for gamle måneder senere. -
Hold det samlede indeks oven i købet for
CLUSTER
(som ikke kan fungere på delvise indekser). Hvis gamle poster aldrig ændrer sig, ville tabelopdeling hjælpe denne opgave meget, da du kun behøver at omgruppere nyere partitioner. Så igen, hvis poster aldrig ændres overhovedet, har du sandsynligvis ikke brug forCLUSTER
.
Hvis du kombinerer de sidste to trin, burde ydeevnen være fantastisk.
Grundlæggende om ydeevne
Du mangler muligvis en af de grundlæggende ting. Alle de sædvanlige præstationsråd gælder:
- https://wiki.postgresql.org/wiki/Slow_Query_Questions
- https://wiki.postgresql.org/wiki/Performance_Optimization