sql >> Database >  >> RDS >> PostgreSQL

Zoekbereik van Postgres-tijdstempel optimaliseren

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 de CLUSTER is klaar.

Vetgedrukte nadruk van mij. Overweeg het alternatief pg_repack :

In tegenstelling tot CLUSTER en VACUUM 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 van CLUSTER 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. Optioneel DROP 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 waarschijnlijk CLUSTER 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



  1. Hoe databases e-commercebedrijven ondersteunen

  2. Topantwoorden op 5 brandende vragen over de COALESCE-functie in SQL Server

  3. Hoe de sortering van een tabel in MySQL te tonen

  4. SQL-selecteer elementen waarbij de som van het veld kleiner is dan N