【问题标题】:Is it better to join two fields together, or to compare them each to the same constant?将两个字段连接在一起更好,还是将它们分别与相同的常数进行比较?
【发布时间】:2010-09-09 12:26:13
【问题描述】:

例如哪个更好:

select * from t1, t2 where t1.country='US' and t2.country=t1.country and t1.id=t2.id

select * from t1, t2 where t1.country'US' and t2.country='US' and t1.id=t2.id

更好,因为数据库工作更少,结果更快。

注意: Sybase,在country+id的两个表上都有索引。

【问题讨论】:

  • sybase,并且country+id的两个表都有索引

标签: sql join


【解决方案1】:

我认为您的问题没有一个全球性的答案。这取决于具体的查询。您必须比较两个查询的执行计划,看看是否存在显着差异。

我个人更喜欢第一种形式:

select * from t1, t2 where t1.country='US' and t2.country=t1.country and t1.id=t2.id

因为如果我想更改文字,只需要更改一项。

【讨论】:

    【解决方案2】:

    这里有很多你忽略的因素。它是什么样的数据库?这些表是否已编入索引?它们是如何编入索引的?这些表有多大?

    (过早的优化是万恶之源!)

    如果“t1.id”和“t2.id”被编入索引,数据库引擎可能会根据这些字段将它们连接在一起,然后使用 WHERE 子句的其余部分来过滤掉行。

    它们可以被编入索引,但非常小,并且都适合一页内存。在这种情况下,数据库引擎可能只是对两者进行全面扫描,而不是加载索引。

    你真的不知道,直到你尝试。

    【讨论】:

    • 尽管这是真的,但这不是问题的主要关注点,您只需提供一些显而易见的事实。
    【解决方案3】:

    我有类似的情况,这是我采取的解决方案:

    选择 * 从 t1 INNER JOIN t2 ON t1.id = t2.id AND t1.country = t2.country AND t1.country = 'US'

    我注意到我的查询在这种情况下运行得更快。我假设加入常量可以节省引擎时间,因为 WHERE 子句将在最后执行。加入然后按“美国”过滤意味着您仍然从表中拉出所有其他国家/地区,然后必须过滤掉您想要的国家/地区。这个方法最后拉的记录比较少,因为它只会找到美国的记录。

    【讨论】:

      【解决方案4】:

      正确答案可能取决于您的 SQL 引擎。对于 MS SQL Server,第一种方法显然更好,因为为统计优化器提供了额外的线索,可以帮助它找到更好(更优)的解析路径。

      【讨论】:

        【解决方案5】:

        我认为这取决于库和数据库引擎。每一个都会以不同的方式执行 SQL,不知道哪一个会被优化。

        【讨论】:

          【解决方案6】:

          我倾向于只在代码中包含一次常量。可能有一种或另一种方式的性能优势,但它可能太小了,只有一个参数的维护优势胜过它。

          【讨论】:

            【解决方案7】:

            如果您希望使查询更通用,也许为目标国家/地区替换一个参数,那么我会使用您的第一个示例,因为它只需要进行一次更改。这样就不用担心以后出错了。

            【讨论】:

              【解决方案8】:

              我怀疑这将取决于表格、数据和元数据。我希望我可以设计出能够以两种方式显示结果的示例 - 基准测试!

              【讨论】:

                【解决方案9】:

                扩展应该与任何体面的优化器等效,但这取决于您使用的数据库以及表上定义的索引。

                我建议使用 EXPLAIN 功能来确定哪个表达式是最佳的。

                【讨论】:

                  【解决方案10】:

                  我认为更好的 SQL 应该是:

                  select * from t1, t2 where t1.id=t2.id 和 t1.country ='US'

                  除非 t2 中的国家/地区可能与 t1 相同的 id 不同,否则无需使用第二个比较“US”。

                  【讨论】:

                    【解决方案11】:

                    我不会使用隐式内部连接,而是显式连接表。

                    由于您希望 id 字段和国家/地区字段都相同,并且您提到两者都已编入索引(我假设在同一个索引中),因此我会将两列都包含在连接中,以便您可以使用索引查找而不是扫描。最后,添加你的 where 子句。

                    SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND t1.country = t2.country WHERE t1.country = 'US'

                    【讨论】:

                      猜你喜欢
                      • 2010-09-21
                      • 2016-11-23
                      • 2020-06-08
                      • 1970-01-01
                      • 2019-10-08
                      • 2011-03-15
                      • 2022-07-05
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多