2

所以我有这个查询在 ~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 正在使用的列添加了一个索引,它没有改变任何内容。

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

4

6 回答 6

10

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

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

如果索引正确,SQL 引擎可以只提取您想要的前四列,而不是整个集合。

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

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
于 2009-01-15T15:12:02.740 回答
2

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

至于索引没有影响,请查看执行计划(不确定如何在 MySQL 中执行此操作 - 也许有人可以编辑它?)。同样,我同意迈克尔的观点,这应该会使事情变得更快(只要 column4 是“选择性的”)。

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

于 2009-01-15T15:26:22.913 回答
1

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

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

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

于 2009-01-15T15:22:51.720 回答
0

尝试运行解释

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)上放一个索引吗?

你能多谈谈你的模型吗?你使用什么索引?你能显示一些解释输出吗?字段使用了哪些类型?

于 2009-01-15T15:33:05.100 回答
0

同意迈克尔提到的索引内容。

此外,在 MySQL 中,您可以通过检查将 EXPLAIN 附加到查询的结果来了解查询的性能,例如

EXPLAIN SELECT * FROM foo_tbl WHERE foobar = 'foo'

将帮助您更好地设计查询,并适当地索引。阅读EXPLAIN 语法使用 EXPLAIN 优化查询

于 2009-01-15T15:34:13.677 回答
0

你是如何运行查询的?

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

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

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

于 2009-01-15T15:13:08.807 回答