为什么索引不会加速此查询?

时间:2017-05-18 11:05:23

标签: sql database performance postgresql

我有两个表usersposts,每个表有500k记录。

我想找到写过100到200个帖子的用户。

我的查询是:

SELECT u.accountid, COUNT(*)
FROM users u
JOIN posts p
ON u.accountid = p.owneruserid
GROUP BY u.accountid
HAVING COUNT(*) BETWEEN 100 AND 200;

我在大约一秒钟内得到答案。

我分别在表accountidowneruserid中的usersposts字段添加了索引,但查询没有加快速度。为什么?

2 个答案:

答案 0 :(得分:3)

HAVING COUNT(*) BETWEEN 100 AND 200;

这部分是解释为什么索引是徒劳的关键。

我们只需要获得成员数在100到200之间的组。这意味着每个组我们都需要准确的成员数。第二点我们没有任何限制(例如WHERE部分),以便获得计数和我们需要遍历表中所有记录的所有组。

索引,例如B-Tree索引有助于根据索引条件找到合适的元素(行)。如果数据以某种方式排序(索引提供顺序),我们可以使用二进制搜索来找到所需的子集。但在我们的例子中,我们需要扫描所有记录。因此无论是否订购都无关紧要。

这就是索引不能加速查询的原因。

答案 1 :(得分:1)

您可以将查询简化为:

SELECT p.owneruserid, COUNT(*)
FROM posts p
GROUP BY p.owneruserid
HAVING COUNT(*) BETWEEN 100 AND 200;

posts(owneruserid)上的索引应该适用于此查询。它是查询的覆盖索引,因此查询可能会快一点。

总体而言,查询似乎需要扫描posts中的所有数据以进行聚合。 HAVING无法利用索引。但是,查询可以使用覆盖索引来减少I / O.