一个主题表包含22k个主题(不多(。用户的topics_ignore表只包含33个主题。我使用这个SQL查询来获取每个用户的主题计数,而不包含被忽略的主题。
SELECT
COUNT(t.topic_id) AS num_topics
FROM topics t
LEFT JOIN topics_ignore i ON i.topic_id = t.topic_id AND i.user_id = 2
WHERE t.forum_id = 1
AND i.topic_id IS NULL
我已经在主题表(topic_id,forum_id(上添加了两个索引,在topics_ignore表(topic_id(上添加了一个索引
经过的时间仍然是0.11015秒,而其他查询在0.00010s的范围内
如何从使用索引中获益,或者如何加快查询速度?
谢谢
我首先要用not exists
:重写查询
select count(*)
from topics t
where
not exists (select 1 from topics_ignore ti where ti.user_id = 2 and ti.topic_id = t.topic_id)
and t.forum_id = 1
然后,您可以创建以下索引,以便快速执行子查询:
topics_ignore(user_id, topic_id)
topics(forum_id, topic_id)
上的索引也可能有所帮助(并不是说列的顺序与原始代码中的不同(。
也就是说,您的查询已经有了不错的执行时间(0.1秒(,而您的性能目标(0.0001秒(似乎非常不合理。
对于此查询:
SELECT COUNT(t.topic_id) AS num_topics
FROM topics t LEFT JOIN
topics_ignore i
ON i.topic_id = t.topic_id AND i.user_id = 2
WHERE t.forum_id = 1 AND i.topic_id IS NULL;
你想要两个索引:
topics(forum_id, topic_id)
topics_ignore(topic_id, user_id)
索引中列的顺序很重要,因此第一个索引与问题中的索引不同。
SELECT /*+RESULT_CACHE*/
COUNT(t.topic_id) AS num_topics
FROM topics t
LEFT JOIN topics_ignore i ON i.topic_id = t.topic_id AND i.user_id = 2
WHERE t.forum_id = 1
AND i.topic_id IS NULL
Result Cache是Oracle 11g中的一个新功能,它完全按照它的名字来做,它缓存查询的结果,并将其放入共享池的一部分。如果您有一个经常执行的查询,并且读取很少更改的数据,则此功能可以显著提高性能。