CLUSTER
Als u van plan bent om CLUSTER
. te gebruiken , de weergegeven syntaxis is ongeldig.
create CLUSTER ticket USING ticket_1_idx;
Eén keer uitvoeren:
CLUSTER ticket USING ticket_1_idx;
Dit kan veel helpen met grotere resultatensets. Niet zozeer voor een enkele geretourneerde rij.
Postgres onthoudt welke index moet worden gebruikt voor volgende aanroepen. Als uw tabel niet alleen-lezen is, verslechtert het effect na verloop van tijd en moet u de tabel met bepaalde tussenpozen opnieuw uitvoeren:
CLUSTER ticket;
Mogelijk alleen op vluchtige partities. Zie hieronder.
Echter , als je veel updates hebt, CLUSTER
(of VACUUM FULL
) kan zelfs slecht zijn voor de prestaties. De juiste hoeveelheid bloat zorgt voor UPDATE
om nieuwe rijversies op dezelfde gegevenspagina te plaatsen en vermijdt de noodzaak om het onderliggende bestand in het besturingssysteem te vaak fysiek uit te breiden. U kunt een zorgvuldig afgestemde FILLFACTOR
. gebruiken om het beste van twee werelden te krijgen:
- Vulfactor voor een sequentiële index die PK is
pg_repack
CLUSTER
neemt een exclusief slot op tafel, wat een probleem kan zijn in een omgeving met meerdere gebruikers. Citaat uit de handleiding:
Wanneer een tabel wordt geclusterd, wordt een
ACCESS EXCLUSIVE
slot wordt erop verkregen. Dit voorkomt andere databasebewerkingen (zowel lezen als schrijven ) vanaf het werken op de tafel tot deCLUSTER
is klaar.
Vetgedrukte nadruk van mij. Overweeg het alternatief pg_repack
:
In tegenstelling tot
CLUSTER
enVACUUM FULL
het werkt online, zonder een exclusief slot op de verwerkte tafels te houden tijdens de verwerking. pg_repack is efficiënt om op te starten, met prestaties die vergelijkbaar zijn met het gebruik vanCLUSTER
rechtstreeks.
en:
pg_repack moet een exclusief slot nemen aan het einde van de reorganisatie.
Versie 1.3.1 werkt met:
PostgreSQL 8.3, 8.4, 9.0, 9.1, 9.2, 9.3, 9.4
Versie 1.4.2 werkt met:
PostgreSQL 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 10
Zoekopdracht
De query is eenvoudig genoeg om op zich geen prestatieproblemen te veroorzaken.
Echter, een woord over juistheid :De BETWEEN
constructie omvat grenzen. Uw zoekopdracht selecteert heel 19 december, plus records van 20 dec. 00:00 uur. Dat is een uiterst onwaarschijnlijk vereiste. De kans is groot dat je echt wilt:
SELECT *
FROM ticket
WHERE created >= '2012-12-19 0:0'
AND created < '2012-12-20 0:0';
Prestaties
Allereerst vraag je:
Waarom selecteert het sequentiële scan?
Uw EXPLAIN
output toont duidelijk een Index Scan , geen sequentiële tabelscan. Er moet een soort van misverstand zijn.
Als je hard wordt gedrukt voor betere prestaties, kun je misschien dingen verbeteren. Maar de nodige achtergrondinformatie staat er niet bij. Mogelijke opties zijn:
-
U kunt alleen de vereiste kolommen opvragen in plaats van
*
om de overdrachtskosten (en mogelijk andere prestatievoordelen) te verlagen. -
Je zou kunnen kijken naar partitionering en zet praktische tijdschijven in aparte tabellen. Voeg indien nodig indexen toe aan partities.
-
Als partitioneren geen optie is, zou een andere verwante maar minder ingrijpende techniek zijn om een of meer partiële indexen toe te voegen. .
Bijvoorbeeld, als u voornamelijk de huidige maand , kunt u de volgende gedeeltelijke index maken:CREATE INDEX ticket_created_idx ON ticket(created) WHERE created >= '2012-12-01 00:00:00'::timestamp;
CREATE
een nieuwe index rechts voor het begin van een nieuwe maand. U kunt de taak eenvoudig automatiseren met een cron-taak. OptioneelDROP
gedeeltelijke indexen voor oude maanden later. -
Bewaar de totale index voor
CLUSTER
(die niet kunnen werken op gedeeltelijke indexen). Als oude records nooit veranderen, zou tabelpartitionering deze taak enorm helpen, aangezien u alleen nieuwere partities opnieuw hoeft te clusteren. Maar nogmaals, als records helemaal niet veranderen, hebt u waarschijnlijkCLUSTER
niet nodig .
Als je de laatste twee stappen combineert, zouden de prestaties geweldig moeten zijn.
Basisprincipes van prestaties
Misschien mis je een van de basisprincipes. Alle gebruikelijke prestatie-adviezen zijn van toepassing:
- https://wiki.postgresql.org/wiki/Slow_Query_Questions
- https://wiki.postgresql.org/wiki/Performance_Optimization