Serdia
Serdia

Reputation: 4428

How to avoid sort operator in a select query

In my select statement I have simple sub-query that grabbing last ExpirationDate within ControlNo.

This subquery significantly slows down the performance. QuoteID is Clustered index on table tblQuotes

Statistics are up to date.

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

Is it possible to find a workaround in this case?

Upvotes: 3

Views: 386

Answers (2)

LearnItDom
LearnItDom

Reputation: 140

If the latest record contains the Latest ExpirationDate, then just use MAX operator similar to below:

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

However, if the ExpirationDate is not always the latest and you just want to get the value of whatever the latest record is then I would suggest similar to below. Get the QouteID value first (assuming this is PK) before getting the ExpirationDate to minimize on sorting while seeking for the expirationdate value.

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;

Upvotes: 1

Hadi
Hadi

Reputation: 37313

Try replacing the subquery:

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

With a windows function if you are looking for maximum value

MAX(ExpirationDate) OVER(PARTITION BY ControlNo)

If you are looking for the first value in a specific order then use:

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

Upvotes: 2

Related Questions