sql >> Databasteknik >  >> RDS >> PostgreSQL

Optimera Postgres tidsstämpel frågeintervall

CLUSTER

Om du tänker använda CLUSTER , den visade syntaxen är ogiltig.

create CLUSTER ticket USING ticket_1_idx;

Kör en gång:

CLUSTER ticket USING ticket_1_idx;

Detta kan hjälpa mycket med större resultatuppsättningar. Inte så mycket för en enda rad som returneras.
Postgres kommer ihåg vilket index som ska användas för efterföljande samtal. Om din tabell inte är skrivskyddad försämras effekten med tiden och du måste köra om med vissa intervall:

CLUSTER ticket;

Möjligen bara på flyktiga partitioner. Se nedan.

Men , om du har många uppdateringar, CLUSTER (eller VACUUM FULL ) kan faktiskt vara dåligt för prestandan. Rätt mängd uppblåsthet tillåter UPDATE att placera nya radversioner på samma datasida och undviker behovet av att fysiskt utöka den underliggande filen i operativsystemet för ofta. Du kan använda en noggrant inställd FILLFACTOR för att få det bästa av två världar:

  • Fyllningsfaktor för ett sekventiellt index som är PK

pg_repack

CLUSTER tar ett exklusivt lås på bordet, vilket kan vara ett problem i en miljö med flera användare. Citerar manualen:

När en tabell håller på att klustras visas en ACCESS EXCLUSIVE låset förvärvas på den. Detta förhindrar alla andra databasoperationer (både läser och skriver). ) från att arbeta på bordet tills CLUSTER är klar.

Djärv betoning min. Överväg alternativet pg_repack :

Till skillnad från CLUSTER och VACUUM FULL det fungerar online, utan att hålla ett exklusivt lås på de behandlade tabellerna under bearbetningen. pg_repack är effektivt att starta upp, med prestanda jämförbar med att använda CLUSTER direkt.

och:

pg_repack måste ta ett exklusivt lås i slutet av omorganisationen.

Version 1.3.1 fungerar med:

PostgreSQL 8.3, 8.4, 9.0, 9.1, 9.2, 9.3, 9.4

Version 1.4.2 fungerar med:

PostgreSQL 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 10

Fråga

Frågan är enkel nog att inte orsaka några prestandaproblem i sig.

Men ett ord om riktighet :BETWEEN konstruktion inkluderar gränser. Din fråga väljer hela 19 december, plus poster från 20 december kl. 00:00. Det är extremt osannolikt krav. Chansen är stor att du verkligen vill:

SELECT *
FROM   ticket 
WHERE  created >= '2012-12-19 0:0'
AND    created <  '2012-12-20 0:0';

Prestanda

Först och främst frågar du:

Varför väljer den sekventiell skanning?

Din EXPLAIN utdata visar tydligt en Indexsökning , inte en sekventiell tabellskanning. Det måste finnas något slags missförstånd.

Om du pressas hårt för bättre prestanda kanske du kan förbättra saker. Men den nödvändiga bakgrundsinformationen finns inte i frågan. Möjliga alternativ inkluderar:

  • Du kan bara fråga efter obligatoriska kolumner istället för * för att minska överföringskostnaderna (och eventuellt andra prestationsfördelar).

  • Du kan titta på partitionering och lägg praktiska tidsskivor i separata tabeller. Lägg till index till partitioner efter behov.

  • Om partitionering inte är ett alternativ skulle en annan relaterad men mindre påträngande teknik vara att lägga till ett eller flera partiella index .
    Till exempel, om du mest frågar den aktuella månaden , kan du skapa följande partiella index:

    CREATE INDEX ticket_created_idx ON ticket(created)
    WHERE created >= '2012-12-01 00:00:00'::timestamp;
    

    CREATE ett nytt index precis före början på en ny månad. Du kan enkelt automatisera uppgiften med ett cron-jobb. Valfritt DROP partiella index för gamla månader senare.

  • Håll det totala indexet utöver det för CLUSTER (som inte kan fungera på partiella index). Om gamla poster aldrig ändras, skulle tabellpartitionering hjälpa den här uppgiften mycket, eftersom du bara behöver klustera nyare partitioner. Återigen om poster aldrig ändras alls, behöver du förmodligen inte CLUSTER .

Om du kombinerar de två sista stegen bör prestanda vara fantastisk.

Grundläggande prestanda

Du kanske saknar en av grunderna. Alla vanliga prestationsråd gäller:

  • https://wiki.postgresql.org/wiki/Slow_Query_Questions
  • https://wiki.postgresql.org/wiki/Performance_Optimization



  1. Hur man automatiserar datainsamling på SQL Server Database Growth

  2. Bulk Infoga i Oracle-databas:Vilket är bättre:FÖR Cursor loop eller en enkel Select?

  3. 12 MySQL/MariaDB Säkerhet Best Practices för Linux

  4. Hur SUBSTRING() fungerar i MariaDB