sql >> Databasteknik >  >> RDS >> PostgreSQL

Indexerad BESTÄLLNING AV med LIMIT 1

Förutsatt att vi har att göra med ett stort bord , ett partiellt index kan hjälpa:

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

Som du redan har fått reda på:att gå ner eller stiga spelar knappast någon roll här. Postgres kan skanna bakåt med nästan samma hastighet (undantag gäller för index med flera kolumner).

Fråga för att använda detta index:

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

Poängen här är att göra indexet mycket mindre , så det borde vara lättare att cache och underhålla.

  1. Du måste välja en tidsstämpel som garanterat är mindre än den senaste.
  2. Du bör återskapa indexet då och då för att skära bort gamla data.
  3. Tillståndet måste vara IMMUTABLE .

Så engångseffekten försämras med tiden. Det specifika problemet är det hårdkodade villkoret:

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

Automatisera

Du kan uppdatera indexet och dina frågor manuellt då och då. Eller så automatiserar du det med hjälp av en funktion som denna:

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

Index:

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

Fråga:

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

Automatisera rekreation med ett cron-jobb eller någon triggerbaserad händelse. Dina frågor kan förbli desamma nu. Men du måste återskapa alla index använda denna funktion på något sätt efter att ha ändrat den. Släpp bara och skapa var och en.

Först...

... testa om du verkligen slår i flaskhalsen med detta.

Prova om ett enkelt DROP index ... ; CREATE index ... gör jobbet. Då kan ditt index ha varit uppsvällt. Dina autovakuuminställningar kan vara avstängda.

Eller prova VACUUM FULL ANALYZE för att få hela tabellen plus index i perfekt skick och kontrollera igen.

Andra alternativ inkludera den vanliga allmänna prestandajusteringen och täckande index, beroende på vad du faktiskt hämtar från tabellen.




  1. Hämta den senaste raden för givet ID

  2. Bas 36 till Base 10 konvertering med endast SQL

  3. Ta bort eller trimma första eller sista tecknen i MySQL-databasen med SQL

  4. Mappning av sammansatta nycklar med EF-kod först