所以我的查询在~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使用的列中添加了一个索引,它没有改变任何内容。
关于导致这种情况的任何想法?
答案 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 syntax和Optimizing queries with EXPLAIN。