当限制id范围的附加子查询比where中的相同查询给出的结果快10倍时,遇到了奇怪的情况。
此查询大约需要10秒:
SELECT COUNT(DISTINCT i.id) AS count FROM
items i
INNER JOIN items_keywords ik ON ik.article_id = i.id AND ik.deleted = 0
INNER JOIN category_keywords catk ON catk.keyword_id = ik.keyword_id
INNER JOIN category cat ON cat.id = catk.category_id AND cat.customer_id = 968
WHERE
i.deleted = 0
AND i.edited = 1
AND i.created >= '2018-12-18'
AND i.created <= '2018-12-20 23:59:59'
解释:
如果我添加额外的where子句来设置最小id,则最多需要1秒:
AND i.id > (SELECT MIN(id) FROM items WHERE created >= '2018-12-01')
解释:
通过设置子查询的i.id范围(在主查询中删除i.created,没有minimum id子句)对其进行测试,耗时10秒,除了子查询行和主查询中没有创建索引外,说明与第一个查询相同。
AND i.id IN (SELECT id FROM items WHERE created >= '2018-12-18' AND created <= '2018-12-20 23:59:59') #subquery takes 0,047s
所以,我应该在索引中做些改变,还是将最小id子查询添加到所有查询中,因为这是一个很大的提升?等待任何建议。
部分规格:mysql:5.6.4
项目表:22m行
项目\u关键词:120m行
分类关键字:70m行
这是我的第一个问题,所以别怪我,教教教我。
附加组件:
下面显示如何为这些表创建表
1条答案
按热度按时间41zrol4v1#
快10倍——听起来像是缓存在缓冲池中的数据和不在缓冲池中的数据之间的区别。每个查询是否都计时两次?
请提供
SHOW CREATE TABLE
每张table;可能会有很多微妙的事情发生。此索引可能会诱使它首先使用:
这个指数是“覆盖”的,因此给了一个额外的推动。
目前,优化器决定从
cat.customer_id = 968
.如果
category_keywords
是一个many:many mapping 表中,请参阅此以获取一些性能提示。IN ( SELECT ... )
可能过慢。EXISTS ( SELECT ... )
可能更快。如果要将内容移动到子查询中,请移动所有
i.
对它进行测试。这样就基本上EXISTS
,并且可以使用PRIMARY KEY(id)
作为完美的索引(无需额外索引。)