【问题标题】:Do I have to use UNION insted of JOIN?我必须使用 ONION 代替 JOIN 吗?
【发布时间】:2012-04-28 17:17:13
【问题描述】:

一篇关于 Optimizing your SQL queries 的文章建议使用 Union insted of OR `cause:

使用联合而不是或

在 OR 情况下使用索引会失去速度优势
至少是 MySQL。因此,尽管索引是,这将没有用
正在应用 1 SELECT * FROM TABLE WHERE COLUMN_A = 'value' OR
COLUMN_B = '价值'

另一方面,使用这样的联合将利用索引。
1- 从表中选择 * COLUMN_A = '值'
2-联合 3- 选择 * 来自
表,其中 COLUMN_B = '值'

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

【问题讨论】:

  • 精明的读者会注意到,这些示例涉及在 不同 列上操作的 ORing 条件,这当然不是偶然的。你自己的手术室是这样的吗?
  • 阳性。你有什么建议?
  • 不在我的领域,所以不能说。但是你可以 EXPLAIN 两个查询,看看 MySql 对它们的看法。
  • @Jon - 废话。很明显,我今天早上只是精明的前半部分。 :-)
  • 我当然假设每个单独的列上都存在索引?否则它不会更有效。

标签: join mysqli union


【解决方案1】:

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

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

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

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

分享和享受。


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

【讨论】:

  • 如果是代码清晰的问题,我会说你是对的,但是 SQL 查询处理可能涉及数百万条记录的巨大 while 循环。如果你不优化这些,你会优化什么?
  • @Neil:根据我的经验,只有在出现性能问题时才能尝试优化。如果并且直到出现性能问题,就没有什么可以优化的,因此优化工作将浪费在不成问题的事情上。我发现最好尽可能编写最干净和最简单的代码,因为 A) 大多数情况下它可以正常工作,并且 B) 当性能问题确实出现时,简单的代码可以易于理解,以便创建性能更好的版本。
  • @Bob_Jarvis:那么意见分歧。我认为,如果优化并不意味着牺牲清晰度,那么您应该这样做。我不认为工会不清楚,而是相反。事实上,有时将长 sql 查询组合成单个选择可能非常难以阅读。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 2012-11-02
    • 1970-01-01
    • 2013-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    相关资源
    最近更新 更多