Das interessiert mich jetzt auch mal. Gut dass ich meine temporären Tabellen noch nicht gelöscht habe
Tabelle mit 270789 Einträgen
Code: Alles auswählen
CREATE TABLE boundary_line
(
gid integer,
osm_id integer,
"name" text,
admin_level text,
boundary text,
way geometry
)
SQL
Code: Alles auswählen
explain analyse select osm_id from boundary_line order by osm_id desc limit 1
Plan
Code: Alles auswählen
"Limit (cost=24451.83..24451.84 rows=1 width=4) (actual time=946.569..946.571 rows=1 loops=1)"
" -> Sort (cost=24451.83..25128.81 rows=270789 width=4) (actual time=946.565..946.565 rows=1 loops=1)"
" Sort Key: osm_id"
" Sort Method: top-N heapsort Memory: 25kB"
" -> Seq Scan on boundary_line (cost=0.00..23097.89 rows=270789 width=4) (actual time=0.010..484.949 rows=271478 loops=1)"
"Total runtime: 946.611 ms"
SQL
Code: Alles auswählen
explain analyse select osm_id from boundary_line where osm_id=(select max(osm_id) from boundary_line)
Plan
Code: Alles auswählen
"Seq Scan on boundary_line (cost=23774.87..47549.74 rows=2 width=4) (actual time=947.986..967.312 rows=1 loops=1)"
" Filter: (osm_id = $0)"
" InitPlan"
" -> Aggregate (cost=23774.86..23774.87 rows=1 width=4) (actual time=910.259..910.261 rows=1 loops=1)"
" -> Seq Scan on boundary_line (cost=0.00..23097.89 rows=270789 width=4) (actual time=0.002..463.268 rows=271478 loops=1)"
"Total runtime: 967.356 ms"
Macht imho dann keinen Unterschied mehr, sind beide gleich ineffizient
Gruß
Frank
Edit zu deinem Edit:
k.A, wieso das nicht anders optimiert wird. Dazu kenne ich mich nicht genug mit den Interna der Datenbank aus. Ich schau aber mal, was mit weiteren Spalten im Query passiert ...
Nochmal ein Edit:
Wie man an den costs sehen, kann ist der initiale seq-scan am teuersten, bei beiden queries. Was bei dem mit Max() halt mehr kostet, sind die zusätzlichen "Abfragen" oder wie man das nennen soll, die durchgeführt werden. Die kosten ja nicht mehr die Welt (2.x), tragen aber zur längeren Laufzeit bei. Wenn postgresql noch einmal seq-scan durchführen würde, um, wie du vermustest, die gefundene ID noch einmal zu holen, würde der Query deutlich länger dauern. Was dem Query das Genick meiner Meinung nach bricht, ist das doppelte Abfragen der Tabelle mit zwei Selects statt einem.