如何在选择查询中避免排序运算符

问题描述 投票:3回答:2

在我的select语句中,我有一个简单的子查询,可以在ExpirationDate中获取最后一个ControlNo

此子查询显着降低了性能。 QuoteID是桌子Clustered index上的tblQuotes

统计数据是最新的。

SELECT
  ControlNo,
  PolicyNumber,
(     
  SELECT TOP 1 Q.ExpirationDate
  FROM tblQuotes Q 
  WHERE Q.ControlNo = tblQuotes.ControlNo
  ORDER BY Q.QuoteID DESC
 )
SUM(Premium) as Premium
FROM tblQuotes
GROUP BY ...

enter image description here

enter image description here

在这种情况下是否有可能找到解决方法?

sql sql-server tsql query-performance sql-execution-plan
2个回答
2
投票

尝试替换子查询:

(     
  SELECT TOP 1 Q.ExpirationDate
  FROM tblQuotes Q 
  WHERE Q.ControlNo = tblQuotes.ControlNo
  ORDER BY Q.QuoteID DESC
 )

如果您正在寻找最大价值,可以使用Windows功能

MAX(ExpirationDate) OVER(PARTITION BY ControlNo)

如果您要查找特定订单中的第一个值,请使用:

FIRST_VALUE(ExpirationDate) OVER(PARTITION BY ControlNo ORDER BY QuoteID DESC)

1
投票

如果最新记录包含最新ExpirationDate,那么只需使用MAX运算符,如下所示:

  SELECT
    ControlNo,
    PolicyNumber,
    MAX(ExpirationDate) ExpirationDate,
    SUM(Premium) as Premium
  FROM tblQuotes
  GROUP BY ControlNo, PolicyNumber;

但是,如果ExpirationDate并不总是最新的,你只想获得最新记录的值,那么我建议类似于下面的。首先获取QouteID值(假设这是PK),然后在获取ExpirationDate时最小化排序,同时寻找expirationdate值。

SELECT q.*, qx.ExpirationDate 
FROM 
  (
    SELECT ControlNo, PolicyNumber, SUM(Premium) as Premium
    FROM tblQuotes t
    GROUP BY ControlNo, PolicyNumber
  ) q
  OUTER APPLY
  (
    SELECT ExpirationDate
    FROM tblQuotes q2
    WHERE q2.QuoteID=(SELECT MAX(QouteID) MaxQouteID FROM tblQuotes q1 WHERE q1.ContolNo=q.ControlNo)
  ) qx;
© www.soinside.com 2019 - 2024. All rights reserved.