0

一篇关于优化 SQL 查询的文章建议使用 Union insted of OR `cause:

使用联合而不是 OR


至少在 MySQL 的 OR 情况下使用索引时,索引失去了速度优势。因此,尽管正在应用索引,但这将无用
1 SELECT * FROM TABLE WHERE COLUMN_A = 'value' OR
COLUMN_B = 'value'

另一方面,像这样使用联合将利用索引。
1- SELECT * FROM TABLE WHERE COLUMN_A = 'value'
2- UNION 3- SELECT * FROM
TABLE WHERE COLUMN_B = 'value'

这个建议在多大程度上是真的?我应该将我的 OR 查询转到 Union 吗?

4

2 回答 2

0

我不建议将此作为一般规则。我这里没有安装 MySQL,所以无法检查生成的执行计划,但在 Oracle 中,计划肯定有很大不同,“OR”计划比“UNION”计划更有效。(基本上,'UNION' 必须执行两个 SELECT,然后合并结果 - 'OR' 只需执行一个 SELECT)。即使是“UNION ALL”计划的成本也高于“OR”计划。坚持“或”。

我强烈建议尽可能编写最清晰、最简单的代码。对我来说,这意味着你应该使用“OR”而不是“UNION”。多年来,我发现尝试“预先优化”某些东西,或者换句话说,猜测我会在哪里遇到性能问题,然后尝试围绕这些问题编写代码,是浪费时间。代码往往会在最糟糕的地方花费大量时间,并且只有在运行代码后才能找到它们。很久以前,我学到了三个我发现在这种情况下有用的规则:

  1. 如果运行。
  2. 让它正常运行。
  3. 让它运行得很快。

优化实际上是您应该做的最后一件事。

分享和享受。


跟进:我没有注意到“或”正在查看不同的列(我的错),但我关于“保持简单”的建议仍然有效。

于 2012-04-17T11:16:24.157 回答
0

将索引想象成电话簿中的姓名会有所帮助。电话簿,你可以说,有一个按姓名自然排序的索引,这意味着,如果你想找到约翰史密斯的所有名字,你几乎不需要时间来找到它。您只需打开电话簿的 S 部分并开始查找 Smith。

现在,如果我告诉您在电话簿中查找姓名为 John Smith 或电话号码为 863-2253 的条目会怎样。没那么快,嗯?为了提供准确的答案,您需要一个电话簿来查找 John Smith,另一个是按电话号码排序的电话簿,以便通过他或她的电话号码查找姓名。

也许更复杂的引擎可以看到这种分离的需要并自动完成,但显然 MySQL 没有。因此,虽然这样做似乎很麻烦,但我向您保证,记录数较高的表的差异是显而易见的。

于 2012-04-17T11:17:08.933 回答