我有一个查询在我们的服务器上需要17-20秒,我想看看我能做些什么来优化它。MySQL5.6将在未来几个月升级到5.7。
查询:
SELECT pm.mid AS mid
FROM
pm_message pm
INNER JOIN pm_index pmi ON pmi.mid = pm.mid
GROUP BY pm.mid
HAVING (MIN(pmi.deleted) > 0 AND MAX(pmi.deleted) < '1535490002')
LIMIT 1000 OFFSET 0;
pm\u消息和pm\u索引中的中间列都是这两个表中的主键。这个表每个表有数百万条记录
select count(*) from pm_message;
3748290
select count(*) from pm_index;
6938947
对改进这个查询有什么建议吗?
我想知道把pm\u index表中的'deleted'列作为索引是否有帮助?
3条答案
按热度按时间vwhgwdsa1#
我将完全重写查询,因为您基本上需要一个在特定范围内删除的不同MID的列表。您不需要显示来自
pm_index
表,所以我将使用关联子查询not exists
接线员。这样mysql就不必对整个数据库进行分组和排序pm_index
表以获得最小值和最大值。查询将受益于对中间字段和已删除字段的多列索引
pm_index
table。sdnqo3pr2#
试试这个。它把事情翻了个底朝外--从pmi开始,然后最小化pm的接触。
我怀疑这是否会有很大帮助——查询似乎需要触及两个表中的几乎所有行。
如果全部
mid
pmi中的值肯定存在于pm
,然后我的EXISTS
子句可以删除。但是你说两张table都有PRIMARY KEY(mid)
? 我怀疑pmi
实际上在pk中有第二列。请提供SHOW CREATE TABLE
.k2arahey3#
这就详细阐述了影子的答案。试着用两个
not exists
条款:确保你有一个索引
pm_index(mid, deleted)
. 索引非常重要。我把它分成两个条款是因为OR
可能会混淆查询优化器。