sql >> Database >  >> RDS >> PostgreSQL

Geïndexeerde ORDER BY met LIMIT 1

Ervan uitgaande dat we te maken hebben met een grote tafel , een gedeeltelijke index zou kunnen helpen:

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

Zoals je al vernam:dalen of stijgen maakt hier nauwelijks uit. Postgres kan met bijna dezelfde snelheid achteruit scannen (uitzonderingen zijn van toepassing op indexen met meerdere kolommen).

Vraag om deze index te gebruiken:

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

Het punt hier is om de index veel kleiner te maken , dus het zou gemakkelijker moeten zijn om te cachen en te onderhouden.

  1. Je moet een tijdstempel kiezen dat gegarandeerd kleiner is dan de meest recente.
  2. Je moet de index van tijd tot tijd opnieuw maken om oude gegevens te verwijderen.
  3. De voorwaarde moet IMMUTABLE zijn .

Het eenmalige effect verslechtert dus na verloop van tijd. Het specifieke probleem is de hard gecodeerde voorwaarde:

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

Automatiseren

U kunt de index en uw zoekopdrachten van tijd tot tijd handmatig bijwerken. Of je automatiseert het met behulp van een functie zoals deze:

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();

Vraag:

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

Automatiseer recreatie met een cronjob of een op triggers gebaseerde gebeurtenis. Uw vragen kunnen nu hetzelfde blijven. Maar u moet alle indices opnieuw maken deze functie op enigerlei wijze te gebruiken nadat u deze hebt gewijzigd. Zet ze gewoon neer en maak ze allemaal.

Eerst ..

... test of je hiermee echt de bottleneck raakt.

Probeer of een eenvoudige DROP index ... ; CREATE index ... doet het werk. Dan is uw index mogelijk opgeblazen. Uw autovacuüm-instellingen zijn mogelijk uitgeschakeld.

Of probeer VACUUM FULL ANALYZE om uw hele tabel plus indices in onberispelijke staat te krijgen en opnieuw te controleren.

Andere opties omvatten de gebruikelijke algemene prestatie-afstemming en dekkingsindexen, afhankelijk van wat u daadwerkelijk uit de tabel haalt.




  1. Maak een database in SQL Server 2017

  2. 5 soorten databasereparaties

  3. Wat te doen (of niet te doen) over de beste wachtstatistieken

  4. SQL Developer 4.0 uitgebracht