我有两个表users
和posts
,每个表有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;
我在大约一秒钟内得到答案。
我分别在表accountid
和owneruserid
中的users
和posts
字段添加了索引,但查询没有加快速度。为什么?
答案 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.