【问题标题】:Which is better for performance, selecting all the columns or select only the required columns while performng join?在执行连接时选择所有列或仅选择所需的列,哪个对性能更好?
【发布时间】:2018-09-05 12:02:56
【问题描述】:

我被要求对一个有很多连接的 SQL Server 查询进行性能调整。

例如

LEFT JOIN 
    vw_BILLABLE_CENSUS_R CEN ON DE.Client = CEN.Client
                             AND CAL.REPORTING_MONTH = CEN.REPORTING_MONTH

vw_Billing_Cenus_R 中有近 25 列,但我们只想使用其中的 3 列。所以我想知道,如果我只选择那些需要的列然后像这样执行连接,而不是从视图或表中选择所有列

LEFT JOIN (SELECT [Column_1], [Column_2], [Column_3] 
           FROM vw_BILLABLE_CENSUS_R) CEN ON DE.Client = CEN.Client
                                          AND CAL.REPORTING_MONTH = CEN.REPORTING_MONTH

那么这会提高性能吗?

【问题讨论】:

  • 为什么不自己比较一下执行计划呢?
  • VIEW 中选择与从TABLE 中选择不同。 VIEW 可以包含多个表本身的多个连接。

标签: sql sql-server sql-server-2008 ssis


【解决方案1】:

我宁愿使用这种方法:

LEFT JOIN 
    vw_BILLABLE_CENSUS_R CEN ON DE.Client = CEN.Client
                             AND CAL.REPORTING_MONTH = CEN.REPORTING_MONTH

比这个

LEFT JOIN (SELECT [Column_1], [Column_2], [Column_3] 
           FROM vw_BILLABLE_CENSUS_R) CEN ON DE.Client = CEN.Client
                                          AND CAL.REPORTING_MONTH = CEN.REPORTING_MONTH

因为在这种情况下:

  1. 让您的查询更简单,
  2. 您不必依赖查询优化器的智能并期望它会消除不必要的列和行
  3. 最后,您可以根据需要在外部 SELECT 中选择尽可能多的列,而无需使用派生表技术。

在某些情况下,当您想消除要即时加入的表中的重复项时,欢迎使用派生表,但恕我直言,您的情况并非如此。

【讨论】:

    【解决方案2】:

    重要的部分是您在最外面的SELECT 上实际使用的列,而不是选择加入的列。 SQL Server 引擎足够聪明,可以意识到如果不需要,他不需要从引用的表(或视图)中检索所有列。

    所以以下 2 个查询应该产生完全相同的查询执行计划:

    SELECT
        A.SomeColumn
    FROM
        MyTable AS A
        LEFT JOIN (
            SELECT
                *
            FROM
                OtherTable AS B) AS X ON A.SomeColumn = X.SomeColumn
    
    SELECT
        A.SomeColumn
    FROM
        MyTable AS A
        LEFT JOIN (
            SELECT
                B.SomeColumn
            FROM
                OtherTable AS B) AS X ON A.SomeColumn = X.SomeColumn
    

    不同之处在于您是否实际使用所选列(在条件 where 或实际检索值中),如下所示:

    SELECT
        A.SomeColumn,
        X.* -- * has all X columns
    FROM
        MyTable AS A
        LEFT JOIN (
            SELECT
                B.*
            FROM
                OtherTable AS B) AS X ON A.SomeColumn = X.SomeColumn
    
    
    SELECT
        A.SomeColumn,
        X.* -- * has only X's SomeColumn
    FROM
        MyTable AS A
        LEFT JOIN (
            SELECT
                B.SomeColumn
            FROM
                OtherTable AS B) AS X ON A.SomeColumn = X.SomeColumn
    

    【讨论】:

      【解决方案3】:

      这取决于存储了多少条记录,但通常会提高性能。 在这种情况下阅读@LukStorms的cmets,我认为他是对的

      【讨论】:

      • 但他加入的是视图,而不是表。我怀疑在这种情况下它会有所帮助。
      • @LukStorms 你是对的。无论如何,最好尽可能少移动数据
      • 嗯,比较两个版本的执行计划应该会给他一个更快的答案。
      • 如果是只从 1 个表中选择的视图,那么他可以更改连接以链接到表本身,并在该子查询中使用视图中的条件。
      • 另一件事,他谈到了多个连接。如果其中一些连接是到同一个视图/表,那么他可以使用 CTE。并多次加入该 CTE。
      猜你喜欢
      • 2014-09-25
      • 1970-01-01
      • 1970-01-01
      • 2021-03-29
      • 2018-12-05
      • 1970-01-01
      • 2020-05-09
      • 1970-01-01
      • 2014-12-08
      相关资源
      最近更新 更多