Ich habe eine einfache Blog-Datenbank in postgres-8.4, die zwei Tabellen enthält, articles
und comments
. Ich habe eine Abfrage (generiert von Django), die den neuesten Artikel vom Typ 'NEWS' abrufen und auch die Anzahl der Kommentare für diesen Artikel ermitteln möchte. Dies geschieht mit der folgenden Abfrage:
SELECT "articles"."id", "articles"."datestamp", "articles"."title", "articles"."shorttitle", "articles"."description", "articles"."markdown", "articles"."body", "articles"."idxfti", "articles"."published", "articles"."type", COUNT("comments"."id") AS "comment__count"
FROM "articles"
LEFT OUTER JOIN "comments" ON ("articles"."id" = "comments"."article_id")
WHERE ("articles"."type"='NEWS')
GROUP BY "articles"."id", "articles"."datestamp", "articles"."title", "articles"."shorttitle", "articles"."description", "articles"."markdown", "articles"."body", "articles"."idxfti", "articles"."published", "articles"."type"
ORDER BY "articles"."datestamp" DESC
LIMIT 1;
Keine dieser Tabellen ist besonders groß, und dennoch dauert diese Abfrage 46 ms. Der Ausführungsplan lautet:
Limit (cost=119.54..119.58 rows=1 width=1150) (actual time=46.479..46.481 rows=1 loops=1)
-> GroupAggregate (cost=119.54..138.88 rows=455 width=1150) (actual time=46.475..46.475 rows=1 loops=1)
-> Sort (cost=119.54..120.68 rows=455 width=1150) (actual time=46.426..46.428 rows=2 loops=1)
Sort Key: articles.datestamp, articles.id, articles.title, articles.shorttitle, articles.description, articles.markdown, articles.body, articles.idxfti, articles.published, articles.type
Sort Method: quicksort Memory: 876kB
-> Hash Left Join (cost=11.34..99.45 rows=455 width=1150) (actual time=0.513..2.527 rows=566 loops=1)
Hash Cond: (articles.id = comments.article_id)
-> Seq Scan on articles (cost=0.00..78.84 rows=455 width=1146) (actual time=0.017..0.881 rows=455 loops=1)
Filter: ((type)::text = 'NEWS'::text)
-> Hash (cost=8.93..8.93 rows=193 width=8) (actual time=0.486..0.486 rows=193 loops=1)
-> Seq Scan on comments (cost=0.00..8.93 rows=193 width=8) (actual time=0.004..0.252 rows=193 loops=1)
Total runtime: 46.574 ms
In der Artikeltabelle ist (unter anderem) folgender Index definiert:
idx_articles_datestamp" btree (datestamp DESC) CLUSTER
Bevor ich es gruppierte, entsprach die Ausführung der Abfrage eher den Schätzungen (ca. 119 ms).
Für mein ungeübtes Auge sieht es so aus, als würde die Sorte hier am meisten Zeit in Anspruch nehmen. Es scheint auch auf allen GROUP zu versuchen , von Feldern zu sortieren, das Problem ist , dass es versucht , auf drei relativ große Felder zu sortieren, body
, markdown
und idx_fti
.
Meine Frage lautet: Ist dies eine unangemessene Zeit, die diese Abfrage in Anspruch nimmt, oder gibt es etwas Offensichtliches, das ich verpasst habe, um diese Abfrage zu beschleunigen? Alle anderen von dieser Blog-Site angeforderten Abfragen benötigen ca. 1-5 ms, um ausgeführt zu werden. Daher dauert diese Abfrage sehr lange. Ich schätze, dass es einen OUTER JOIN und einen SORT gibt, die nicht wirklich helfen. Ich bin jedoch kein Experte. Wenn also jemand Vorschläge hat, wäre das äußerst nützlich.