HiveBrain v1.2.0
Get Started
← Back to all entries
snippetsqlMinor

Improve sort performance in PostgreSQL?

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
improvesortpostgresqlperformance

Problem

I've got a simple blog database in postgres-8.4 which has two tables, articles and comments. I have a query (generated by Django) that wants to get the latest article of type 'NEWS' and also find the number of comments for that article. It does that with the following query:

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;


None of these tables is particularly large, and yet that query takes 46ms. The execution plan is:

```
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 (c

Solution

Another way to rewrite the query, with an inline subquery:

SELECT id,
       datestamp,
       title,
       shorttitle,
       description,
       markdown,
       body,
       idxfti,
       published,
       type,
       ( SELECT COUNT(*) 
         FROM comments 
         WHERE articles.id = comments.article_id
       ) AS comment__count
FROM articles 
WHERE type = 'NEWS'
ORDER BY datestamp DESC 
LIMIT 1

Code Snippets

SELECT id,
       datestamp,
       title,
       shorttitle,
       description,
       markdown,
       body,
       idxfti,
       published,
       type,
       ( SELECT COUNT(*) 
         FROM comments 
         WHERE articles.id = comments.article_id
       ) AS comment__count
FROM articles 
WHERE type = 'NEWS'
ORDER BY datestamp DESC 
LIMIT 1

Context

StackExchange Database Administrators Q#17209, answer score: 9

Revisions (0)

No revisions yet.