2012-04-09 73 views
2

我有一个拥有170,000条记录的拥抱表。sql查询限制行数之间的性能差异

是什么这个查询之间的区别

Showing rows 0 - 299 (1,422 total, Query took 1.9008 sec) 
    SELECT 1 FROM `p_apartmentbuy` p 
    where 
    p.price between 500000000 and 900000000 
    and p.yard = 1 
    and p.dateadd between 1290000000 and 1320000000 
    ORDER BY `p`.`id` desc 
    limit 1669 

解释 enter image description here

这一个:

Showing rows 0 - 299 (1,422 total, Query took 0.2625 sec) 
    SELECT 1 FROM `p_apartmentbuy` p 
    where 
    p.price between 500000000 and 900000000 
    and p.yard = 1 
    and p.dateadd between 1290000000 and 1320000000 
    ORDER BY `p`.`id` desc 
    limit 1670 

解释: enter image description here

这两查询正在使用同一数据的一个表,并具有相同的地方clasue,但只有限制行数不同

回答

2

MySQL有一个排序缓冲区。当要排序的东西太大时,它会对大块进行排序,然后将它们合并排序。这被称为“filesort”。您的第1670行显然只是溢出排序缓冲区。

查看更多详细信息here

现在为什么它选择另一个关键的内存排序...我不太确定;但显然它的策略不太好,因为它最终变慢了。

+0

有同样的页面缓存在MySQL?这在SQL Server中很常见,因为数据在内存中,第二次运行速度更快。 – JNK 2012-04-09 16:01:37

+0

tnx for answer。我如何禁用这个缓冲区进行排序? – Hamidreza 2012-04-09 16:05:32

+1

你可以设置'@@ sort_buffer_size',但这是一个破解。有一件事要尝试的是“选择...使用指数(码)”,以确保使用更快的策略;看看'EXPLAIN'说了些什么。 – Amadan 2012-04-09 16:14:53

1

回顾:奇怪的是,该查询返回更多的行运行得更快

这个缓冲VS文件排序,排序1400只记录不涉及不到1秒钟

需要以及第一说明显示查询优化器做线性扫描,第二个解释使用索引显示它。即使是部分有用的指数通常也比无。

在内部,mysql维护有关索引大小的统计信息,并试图猜测哪个索引或线性扫描是否会更快。这个估计数据是特定数据的,我已经看到mysql在100个中使用了99次正确的索引,但是每隔一段时间选择一个不同的索引并且将查询运行得慢50倍。

您可以覆盖内置的查询优化器,并指定索引手动使用,用SELECT ... FROM ... FORCE INDEX(...)