优化查询而不是使用order by

时间:2011-01-05 06:15:26

标签: mysql sql

我想运行一个简单的查询来获取表中“n”个最旧的记录。 (它有一个creation_date列。)

如果不使用“order-by”,我怎么能得到它。这是一张非常大的桌子,并且在整个桌子上使用订单来获得“n”记录并不那么令人信服。

(假设n<<表的大小)

4 个答案:

答案 0 :(得分:3)

当您担心表现时,您可能不应过早放弃使用订单。

这样的查询可以实现为适当索引支持的Top-N查询,它运行速度非常快,因为它不需要对整个表进行排序,甚至不需要对选择行进行排序,因为数据已经在索引。

示例:

select *
  from table
 where A = ?
 order by creation_date 
 limit 10;

没有适当的索引,如果您拥有大量数据,它将会很慢。但是,如果您创建这样的索引:

create index test on table (A, creation_date );

查询将能够以正确的顺序开始获取行而不进行排序,并在达到限制时停止。

食谱:将where列放在索引中,然后按列排序。

如果没有where子句,只需将order by放入索引即可。 order by必须与索引定义匹配,特别是如果存在混合的asc / desc命令。

索引的Top-N查询是性能王 - 确保使用它们。

我进一步阅读的链接很少(全是我的):

How to use index efficienty in mysql query

http://blog.fatalmind.com/2010/07/30/analytic-top-n-queries/(以Oracle为中心)

http://Use-The-Index-Luke.com/(尚未涵盖前N个查询,但这将在2011年出现)。

答案 1 :(得分:2)

我之前没有测试过这个概念,但尝试在creation_date列上创建索引。哪个会自动按行升序排序。然后,您的选择查询可以使用orderby creation_date desc和Limit 20来获取前20条记录。数据库引擎应该意识到索引已经完成了工作排序而实际上不需要排序,因为索引已经在保存时对其进行了排序。它需要做的就是从索引中读取最后20条记录。

值得一试。

答案 2 :(得分:1)

creation_date上创建索引并使用order by creation_date asc|desc limit n进行查询,响应速度非常快(事实上它不会更快)。对于“最新n”方案,您需要使用desc

如果您希望对此查询有更多限制(例如where state='LIVE'),那么查询可能会变得非常慢,您需要重新考虑索引策略。

答案 3 :(得分:0)

如果您对某些数据进行分组,则可以使用Group By,然后使用Having子句选择特定记录。