我对这两个查询感到困惑,他们的查询速度不稳定。这是我的两个表格方案;
帖子表:( id,title,date等...)[日期索引]
关系表:(news_id,relation_id)[两行和每行都有索引]
查询A:
SELECT *
FROM posts
WHERE id IN (
SELECT news_id
FROM relationships
WHERE relation_id IN (?)
)
AND status = 1
ORDER BY `date` DESC
查询B:
SELECT *
FROM posts AS p
INNER JOIN relationships AS r ON r.news_id = n.id
WHERE r.relation_id IN (?)
AND n.status = 1
ORDER BY n.date DESC
现在很奇怪的部分是测试结果;首先尝试一个有30行的relation_id;
查询A:总共30个,查询耗时5.56秒
查询B:共30次,查询耗时0.03秒
A在较少行上较慢,B在较少行上较慢。接下来尝试一个有3k行的relation_id;
查询A:共计3,850,查询耗时0.05秒
查询B:共计3,850,查询耗时0.70秒
所以这让我很困惑,现在有更多的数据A更快。最后一个,尝试使用+10k行的多个relation_id;例; relation_id IN (1, 2, 3, 4)
查询A:总计18,906,查询耗时0.01秒
查询B:总计18,906,查询耗时3.34秒
那我该怎么办?查询A是这么多行的速度,但行速度较慢而速度慢。这个查询还有另一种真实的方式建议吗? (抱歉我的英语或语法错误)
修改
这是SQL EXPLAIN s;
查询A有30行
查询B有30行
查询A有18k行
查询B,行数为18k
答案 0 :(得分:0)
很奇怪,但那是MySQL; - )
优化器认为status = 1
是一个强大的限制。如果这样,你可以通过
select status=1, count(*) as num from posts group by status=1
如果表格的一小部分只有status=1
,那么从mysqls的角度来看,30行解决方案仍然非常好。
如果大部分有status = 1
,那么您应该尝试使用
from posts ignore index (status) ...
或
from posts force index (id) ...
强制执行解决方案。
您可以通过
获取更多信息explain select count(*) from relationships where relation_id in (1)
根据它的索引统计信息显示优化器所期望的大小。
固定索引提示的问题在于它们是固定的。这意味着他们适用于好的和坏的场景。
有时临时表有助于避免这种情况,您可以将相关关系存储在其中。