2013-05-12 47 views
1

我对这两个查询非常困惑,他们有不稳定的查询速度。这是我的两个表格方案;两个不稳定的查询性能

帖子表:(ID,标题,日期等...)[日期索引]

关系表:(news_id,relation_id)都与每行有索引]

查询:

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;

查询:30总计,查询花费5.56秒

查询B:30总计,查询花费0.03秒

A是上更少的行缓慢,B是加快上更少的行。接下来尝试一个有3k行的relation_id;

查询:3850总计,查询花费0.05秒

查询B:3850总计,查询花费0.70秒

因此,这是我感到困惑,现在有更多的数据A更快速。最后一个,尝试使用+ 10k行的多关系id;例; relation_id IN (1, 2, 3, 4)

查询:18906总计,查询花费0.01秒

查询B:18906总计,查询花费3.34秒

那么,应该怎么办?查询A在很多行上速度很快,但行速度较慢。这个查询的任何其他真实的方式建议? (对不起我的英语不好或语法错误)

编辑

这里是SQL EXPLAIN S;

用30行

查询Query A with 30 rows

查询乙与30行 query B

查询以18K行 query a

查询乙连18k行 query b 2

+0

你可以给出30行示例和一个大例子的解释吗? “在哪里”不应该花5秒钟。你确定没有其他问题在哪里干扰你的测量?它是否可重复? – flaschenpost 2013-05-12 15:56:18

+0

'posts.id'是否有索引? – 2013-05-12 15:57:35

+0

@JoachimIsaksson是的,它的主要 – musa 2013-05-12 15:58:08

回答

0

很奇怪,但那是MySQL ;-)

优化程序认为status = 1是一个强大的限制。如果成立,你会得到通过

select status=1, count(*) as num from posts group by status=1 

如果只是你的表的一小部分具有status=1那么30行的解决方案仍是从mysqls的观点相当不错。

如果很大一部分具有status = 1那么你应该尝试与

from posts ignore index (status) ... 

from posts force index (id) ... 

强制执行,其中,在溶液中查询。

更多信息,您可以通过

explain select count(*) from relationships where relation_id in (1) 

,显示优化希望在此基础上的指数统计,其尺寸得到。

具有固定折射率提示的问题是,它们被固定。这意味着他们会申请好的和不好的情况。

有时一个临时表有助于避免这一点,你可以存储相关关系成。

+0

实际上,我尝试没有“where status”和“order by”,瓶颈看起来像点菜。没有“order by”的查询B用+ 10k行花了0.0082秒 – musa 2013-05-12 16:53:25