sql >> Database teknologi >  >> RDS >> PostgreSQL

Indekseret BESTIL AF med LIMIT 1

Forudsat at vi har at gøre med et stort bord , et delvist indeks kan hjælpe:

CREATE INDEX tbl_created_recently_idx ON tbl (created_at DESC)
WHERE created_at > '2013-09-15 0:0'::timestamp;

Som du allerede har fundet ud af:nedadgående eller opstigning betyder næppe noget her. Postgres kan scanne baglæns med næsten samme hastighed (undtagelser gælder for indekser med flere kolonner).

Forespørgsel om at bruge dette indeks:

SELECT * FROM tbl
WHERE  created_at > '2013-09-15 0:0'::timestamp -- matches index
ORDER  BY created_at DESC
LIMIT  1;

Pointen her er at gøre indekset meget mindre , så det burde være nemmere at cache og vedligeholde.

  1. Du skal vælge et tidsstempel, der med garanti er mindre end det seneste.
  2. Du bør genskabe indekset fra tid til anden for at afskære gamle data.
  3. Betingelsen skal være IMMUTABLE .

Så engangseffekten forværres over tid. Det specifikke problem er den hårdkodede tilstand:

WHERE created_at > '2013-09-15 0:0'::timestamp

Automatiser

Du kan opdatere indekset og dine forespørgsler manuelt fra tid til anden. Eller du automatiserer det ved hjælp af en funktion som denne:

CREATE OR REPLACE FUNCTION f_min_ts()
  RETURNS timestamp LANGUAGE sql IMMUTABLE AS
$$SELECT '2013-09-15 0:0'::timestamp$$

Indeks:

CREATE INDEX tbl_created_recently_idx ON tbl (created_at DESC);
WHERE created_at > f_min_ts();

Forespørgsel:

SELECT * FROM tbl
WHERE  created_at > f_min_ts()
ORDER  BY created_at DESC
LIMIT  1;

Automatiser rekreation med et cron-job eller en trigger-baseret begivenhed. Dine forespørgsler kan forblive de samme nu. Men du skal genskabe alle indekser bruge denne funktion på nogen måde efter at have ændret den. Bare slip og opret hver enkelt.

Først ...

... test, om du rent faktisk rammer flaskehalsen med dette.

Prøv om et simpelt DROP index ... ; CREATE index ... gør jobbet. Så er dit indeks muligvis blevet oppustet. Dine autovakuumindstillinger er muligvis slået fra.

Eller prøv VACUUM FULL ANALYZE for at få hele dit bord plus indekser i perfekt stand og tjek igen.

Andre muligheder inkludere den sædvanlige generelle præstationsjustering og dækkende indekser, afhængigt af hvad du rent faktisk henter fra tabellen.




  1. Sådan ændres en kolonne fra Null til Ikke Null i SQL Server

  2. 2 måder at returnere rækker, der ikke indeholder numeriske værdier i Oracle

  3. Hvad er den bedste løsning til pooling af databaseforbindelser i python?

  4. Sådan gør du RAND() deterministisk i SQL Server