You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SQL左连接查询性能优化求助:如何利用索引提速统计查询?

优化未忽略主题统计查询的实用方案

咱们来一步步拆解你的问题,找到让查询提速的关键点:你的核心需求是统计用户ID=2未忽略的、属于forum_id=1的主题数,现有查询慢的根源其实在索引的设计匹配度上,下面是具体的优化思路:

1. 给topics_ignore建复合索引(最关键的一步)

你现在给topics_ignore只建了topic_id的单字段索引,但查询里是同时用user_id=2topic_id做关联过滤的。单字段索引在这里的效率很低——数据库需要先找到所有匹配topic_id的记录,再从中筛出user_id=2的,相当于多做了一次过滤。

换成**复合索引(user_id, topic_id)**就不一样了:数据库可以直接定位到用户ID=2的所有忽略主题,不用额外过滤,关联时的查找速度会飙升。

执行这条SQL创建索引:

CREATE INDEX idx_topics_ignore_user_topic ON topics_ignore(user_id, topic_id);

2. 优化topics表的索引(锦上添花)

你的topics表现有topic_idforum_id的单字段索引,其实可以合并成复合索引(forum_id, topic_id)。因为你的查询第一步是筛选forum_id=1,这个复合索引能让数据库直接取出该论坛下的所有topic_id,不用先查forum_id索引再回表取topic_id,减少了IO开销。

创建索引的SQL:

CREATE INDEX idx_topics_forum_topic ON topics(forum_id, topic_id);

3. 换用NOT EXISTS写法(小数据集下更高效)

因为topics_ignore只有33条数据,用NOT EXISTS的写法有时候会比左连接+IS NULL更高效,数据库的优化器可能会选择更轻量的执行计划,逻辑上和原查询完全等价:

SELECT COUNT(t.topic_id) AS num_topics 
FROM topics t 
WHERE t.forum_id = 1 
AND NOT EXISTS (
    SELECT 1 
    FROM topics_ignore i 
    WHERE i.topic_id = t.topic_id 
    AND i.user_id = 2
);

为什么原查询慢?

再回头看原查询的执行逻辑:数据库会先扫描topics表中forum_id=1的所有记录,然后对每条记录去topics_ignoretopic_id索引里查找,还要额外过滤user_id=2。这个过程中,每条topics的记录都要做一次“先找topic_id再筛user_id”的操作,累计起来就拖慢了速度。而复合索引(user_id, topic_id)直接把用户2的忽略主题打包成了一个小集合,关联时直接匹配,效率自然就上去了。

内容的提问来源于stack exchange,提问作者Lars Vegas

火山引擎 最新活动