两个不稳定查询性能

时间:2013-05-12 15:51:26

标签: mysql join relational-database relationship

我对这两个查询感到困惑,他们的查询速度不稳定。这是我的两个表格方案;

帖子表:( 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行 Query A with 30 rows

查询B有30行 query B

查询A有18k行 query a

查询B,行数为18k query b 2

1 个答案:

答案 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)

根据它的索引统计信息显示优化器所期望的大小。

固定索引提示的问题在于它们是固定的。这意味着他们适用于好的和坏的场景。

有时临时表有助于避免这种情况,您可以将相关关系存储在其中。