如何避免 select 查询中的排序运算符
How to avoid sort operator in a select query
在我的 select 语句中,我有一个简单的子查询,它获取 ControlNo
中的最后一个 ExpirationDate
。
此子查询显着降低了性能。
QuoteID
在 table tblQuotes
上 Clustered index
统计数据是最新的。
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 ...
在这种情况下是否可以找到解决方法?
尝试替换子查询:
(
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)
如果最新记录包含最新过期日期,则只需使用类似于以下的 MAX 运算符:
SELECT
ControlNo,
PolicyNumber,
MAX(ExpirationDate) ExpirationDate,
SUM(Premium) as Premium
FROM tblQuotes
GROUP BY ControlNo, PolicyNumber;
但是,如果 ExpirationDate 并不总是最新的,而您只想获取最新记录的值,那么我建议类似于以下内容。在获取 ExpirationDate 之前先获取 QouteID 值(假设这是 PK),以在寻找过期日期值时最小化排序。
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;
在我的 select 语句中,我有一个简单的子查询,它获取 ControlNo
中的最后一个 ExpirationDate
。
此子查询显着降低了性能。
QuoteID
在 table tblQuotes
Clustered index
统计数据是最新的。
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 ...
在这种情况下是否可以找到解决方法?
尝试替换子查询:
(
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)
如果最新记录包含最新过期日期,则只需使用类似于以下的 MAX 运算符:
SELECT
ControlNo,
PolicyNumber,
MAX(ExpirationDate) ExpirationDate,
SUM(Premium) as Premium
FROM tblQuotes
GROUP BY ControlNo, PolicyNumber;
但是,如果 ExpirationDate 并不总是最新的,而您只想获取最新记录的值,那么我建议类似于以下内容。在获取 ExpirationDate 之前先获取 QouteID 值(假设这是 PK),以在寻找过期日期值时最小化排序。
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;