加速使用exists

时间:2016-03-02 03:08:20

标签: sql performance postgresql optimization

我是SQL新手并且最终设法将一个返回我正在寻找的值的查询放在一起!唯一的问题是,这运行得非常慢,大概是因为存在子句。我希望增加LIMIT可以显着加快速度,但不幸的是我从经验上发现这不是真的。

还有另一种方法来编写此查询,以“可接受的”速度返回相同的值吗?我意识到“可接受”是主观的,但我只是在寻找新的方法。

以下是使用的表格:

content
---------------------------------------
id            |    Int
---------------------------------------

content_revision
---------------------------------------
id            |    Int
content_id    |    ForeignKey (content)
---------------------------------------

这是我的慢查询:

SELECT outer_content.id AS "TEN_MOST_RECENT_CONTENTS_WITH_ONE_REVISION" 
    FROM content outer_content 
    JOIN content_revision ON outer_content.id = content_revision.content_id 
    WHERE EXISTS (
        SELECT inner_content.id 
            FROM content_revision 
            JOIN content inner_content ON content_revision.content_id = inner_content.id 
            WHERE outer_content.id = inner_content.id 
            GROUP BY inner_content.id HAVING count(*) = 1
    ) 
ORDER BY ts_created DESC 
LIMIT 10;

我有兴趣找到“TEN_MOST_RECENT_CONTENTS_WITH_ONE_REVISION”

2 个答案:

答案 0 :(得分:4)

你真的需要内心选择吗?您可以使用:

 SELECT inner_content.id, MAX(ts_created) 
            FROM content_revision 
            JOIN content inner_content ON content_revision.content_id = inner_content.id 
            GROUP BY inner_content.id HAVING count(*) = 1
            ORDER BY MAX(ts_created) DESC 
            LIMIT 10;

由于您使用的是分组,如果您想按ts_created订购,则可以使用MAX(ts_created)。由于HAVING

,无论如何只有一条记录

答案 1 :(得分:1)

您根本不需要使用WHERE EXISTS条件。您所要做的只是GROUP BY content.id, content.ts_created并添加HAVING count(content_revision.*) = 1,然后限制,订购等......

-- get ten most recent contents with one revision
SELECT content.id, content.ts_created 
FROM content
JOIN content_revision ON content.id = content_revision.content_id 
GROUP BY content.id, content.ts_created 
HAVING count(content_revision.*) = 1
ORDER BY content.ts_created DESC 
LIMIT 10;