【问题标题】:Avoiding Order By in T-SQL避免在 T-SQL 中排序
【发布时间】:2017-08-07 15:02:24
【问题描述】:

以下示例查询是我的主要查询的一部分。我发现下面查询中的 SORT 运算符消耗了 30% 的成本。

为了避免排序,需要创建索引。有没有其他方法可以优化这段代码。

SELECT TOP 1 CONVERT( DATE, T_Date) AS T_Date
FROM TableA
WHERE ID = r.ID
 AND Status = 3
 AND TableA_ID >ISNULL((
                        SELECT TOP 1 TableA_ID
                        FROM TableA
                        WHERE ID = r.ID
                            AND Status <> 3
                        ORDER BY T_Date DESC 
                        ), 0)
ORDER BY T_Date ASC

【问题讨论】:

  • 添加索引到T_Date?
  • r 表在哪里?
  • 是的,但是最好查看整个代码以了解您要做什么
  • 一些样本数据和期望的结果也会有所帮助...
  • 考虑到你正在寻找一行和一个值,考虑 min() / max() 而不是 top 1 asc / desc

标签: tsql sql-server-2012 query-optimization


【解决方案1】:

看起来您可以使用not exists 而不是排序。我认为通过使用 CTE 或派生表而不是标量子查询,您可能会获得更好的性能提升。

select *
from r ... left outer join
(
    select ID, min(t_date) as min_date from TableA t1
    where status = 3 and not exists (
        select 1 from TableA t2
        where   t2.ID = t1.ID
            and t2.status <> 3 and t2.t_date > t1.t_date
    )
    group by ID
) as md on md.ID = r.ID ...

select *
from r ... left outer join
(
    select t1.ID, min(t1.t_date) as min_date
    from TableA t1 left outer join TableA t2
        on t2.ID = t1.ID and t2.status <> 3
    where t1.status = 3 and t1.t_date < t2.t_date
    group by t1.ID
    having count(t2.ID) = 0
) as md on md.ID = r.ID ...

您似乎还依赖于标识列,但不清楚这些值的含义。我基本上忽略它并改用日期列。

【讨论】:

    【解决方案2】:

    试试这个:

    SELECT TOP 1 CONVERT( DATE, T_Date) AS T_Date
    FROM TableA a1
    LEFT JOIN (
        SELECT ID, MAX(TableA_ID) AS MaxAID
        FROM TableA
        WHERE Status <> 3
        GROUP BY ID
    ) a2 ON a2.ID = a1.ID AND a1.TableA_ID > coalesce(a2.MAXAID,0)
    WHERE a1.ID = r.ID AND a1.Status = 3
    ORDER BY T_Date ASC
    

    TOP 1 与无法解释的 r 别名结合使用让我很担心。几乎可以肯定,有一种MUCH更好的方法可以将这些数据放入您的结果中,而无需在子查询中执行此操作(除非这是针对APPLY 操作)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-11
      • 2010-09-06
      • 1970-01-01
      • 2016-07-09
      • 1970-01-01
      • 2019-11-20
      • 1970-01-01
      相关资源
      最近更新 更多