我正在尝试调整我的MySQL查询,但遇到了一个我不理解的问题(因此无法修复)。从本质上讲,如果它们位于自己的表中,它可以快速排序165,000行,而不是它们是更大表的子集。
表fl6有200万行。它有一个索引x1(departure_out)。 departure_out是日期类型。
以下选项查找165,916行。需要0.1秒。
select count(*)
from fl6
where departure_out > "2013-04-01"
and departure_out < "2013-04-05";
以下select具有相同的where子句,但对价格进行排序。这需要0.5秒。 0.4秒排序165,000行。
select id
from fl6
where departure_out > "2013-04-01"
and departure_out < "2013-04-05"
order by price_total limit 1;
我想看看它是否会更快,所以,我创建了一个只包含165,916行的小表。然后我就这样做了。花了0.16秒。
select id
from fl6_small
order by price_total limit 1;
因此,它可以相当快地排序165,000行,但如果它是较大表的子集,则需要两倍多的时间?我怎么做到这一点?为什么不同?
一些事情:我已经尝试在(价格)和(departure_out,价格)上设置索引。这没什么区别。无论如何,如果fl6_small中的搜索显示即使没有它也可以排序的速度,那么索引就没有必要了。
编辑:
(编辑上面的一些行数和时间以匹配用于解释计划的表)
解释计划:
+----+-------------+-------+-------+---------------+------+---------+------+--------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-----------------------------+
| 1 | SIMPLE | fl6 | range | x1 | x1 | 3 | NULL | 160493 | Using where; Using filesort |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-----------------------------+
答案 0 :(得分:1)
不同之处在于,在第一种情况下,MySQL将创建一个包含165000行的临时表,并在没有索引的情况下对它们进行排序。即使price列上有索引,也不能用于排序。
您的小表可能能够使用索引进行排序,因此速度更快。
答案 1 :(得分:0)
您可以使用EXPLAIN语句检查查询的瓶颈http://dev.mysql.com/doc/refman/5.0/en/explain.html 还有http://dev.mysql.com/doc/refman/5.0/en/optimization.html
答案 2 :(得分:0)
这可能是由于一些问题造成的。
Nitpicky点 - 在大表中你做的不仅仅是一个简单的排序,你首先寻找记录,然后排序。在小表上,您没有通过depature_time搜索。但这是一个小小的作弊,因为较大的表,为了知道使用哪个n,它首先必须建立表。如果它被索引了,那么你的测试显示它不太可能显着......它仍然需要0.5秒的0.1秒。尝试小桌子上的where子句,应该花费更多的时间。如果没有,那么它指向:
其次,* 缓存未命中 : *
2,000K记录可能远远超过您正在使用的计算机上的150K记录,除非您有一个专用于mysql的盒子,增加了缓存未命中的可能性。这些未命中可能是一个更大的惩罚,即使你有一个n ^ 2种或更糟的记录加载在内存和内存对齐。如果你在一个有很多ram的盒子上运行这些测试,假设其他条件相同,那么差异应该会少一些。