将ORDER BY子句添加到MySQL查询使其在约30秒内返回,从~0.5开始

时间:2009-01-15 15:09:24

标签: mysql performance indexing sql-order-by

所以我的查询在~0.5秒时相对较快,但是当我添加一个ORDER BY子句时,它会跳到近30秒。

原始查询:(约0.5秒后返回)

SELECT table1.*,table2.* FROM table1 LEFT OUTER JOIN table2 ON table1.column2=table2.column3 WHERE table1.column1='value' LIMIT 4

使用ORDER BY进行查询:(在~30秒内返回)

SELECT table1.*,table2.* FROM table1 LEFT OUTER JOIN table2 ON table1.column2=table2.column3 WHERE table1.column1='value' ORDER BY table1.column4 DESC LIMIT 4

注意我在ORDER BY使用的列中添加了一个索引,它没有改变任何内容。

关于导致这种情况的任何想法?

6 个答案:

答案 0 :(得分:10)

这需要更长的时间,因为查询不能只选择它找到的前4个项目。它必须对整个列表进行排序,然后从中选择前4个。

通过添加包含table1 {column4,...}的索引来解决此问题。如果您只需要表1中的几列(并且它们很窄),我会将它们 all 添加到索引(covering index)。

如果索引正确,SQL引擎只能拉出你想要的前四列 - 而不是整个集合。

如果你有索引并且它没有帮助,请使用EXPLAIN运行查询以查看执行计划的样子(好的提示,@ IroGoofy):

EXPLAIN 
  SELECT table1.*,table2.* 
  FROM table1 
  LEFT OUTER JOIN table2 ON table1.column2=table2.column3 
  WHERE table1.column1='value' ORDER BY table1.column4 DESC LIMIT 4

答案 1 :(得分:2)

赞同迈克尔的解释,+ 1。

关于索引没有区别,请看一下执行计划(不确定如何在MySQL中执行此操作 - 也许有人可以编辑它?)。同样,我同意迈克尔的看法,这应该会让事情变得更快(只要第4列是“选择性的”)。

@kogus:检索整个结果集到客户端与排序结果集不同,排序应该在服务器上进行,而不需要通过网络传输所有结果

答案 2 :(得分:1)

table1.column1索引了吗?如果是,那么查询优化器将使用该索引从table1中选择初始行集,因为它最坏的是索引范围扫描(非常快)。

如果此查询是经常运行的查询,则可以通过索引(column1,column4)获得所需的性能。我不太了解MySQL,但使用Oracle,你可以通过索引(column1,column4,column2)来提高性能,这将使优化器从索引中完成所有工作,而不是触摸表数据。

但是,添加索引是一种权衡:它会增加每次插入(或更新索引列)所花费的时间,使数据库变大,并可能导致整体减速,因为内存不足资源(即缓冲区缓存)被分配给新索引。

答案 3 :(得分:0)

你是如何运行查询的?

一些工具通常只检索前100个左右的记录,并根据需要下拉更多记录。

添加ORDER BY会强制该工具检索整个数据集。

如果您在MySql浏览器中,请尝试使用ORDER BY运行,然后使用CTRL-END滚动到数据网格的底部。这需要多长时间?

答案 4 :(得分:0)

尝试运行explain

EXPLAIN SELECT table1.*,table2.* FROM table1 LEFT OUTER JOIN table2 ON table1.column2=table2.column3 WHERE table1.column1='value' ORDER BY table1.column4 DESC LIMIT 4

这可能会告诉你MySQL正在做一个文件排序。你能把索引放在(column1,column4)吗?

您能告诉您有关您的模特的更多信息吗?你使用什么索引?你能展示一些解释输出吗?这些领域使用的是哪种类型?

答案 5 :(得分:0)

同意Michael提到的索引内容。

此外,在MySQL中,您可以通过检查将EXPLAIN预先添加到查询中的结果来了解有关查询性能的大量信息,例如

EXPLAIN SELECT * FROM foo_tbl WHERE foobar = 'foo'

可以帮助您更好地设计查询,并进行适当的索引。阅读EXPLAIN syntaxOptimizing queries with EXPLAIN