Как избежать оператора сортировки в запросе выбора - PullRequest
0 голосов
/ 23 февраля 2019

В моем утверждении 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

Можно ли найти обходной путь в этом случае?

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Если последняя запись содержит дату последнего истечения срока действия, просто используйте оператор MAX, аналогичный приведенному ниже:

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

Однако, если срок действия истечения не всегда последний, и вы просто хотите получить значение любогопоследняя запись, то я бы предложил аналогичный ниже.Сначала получите значение 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;
0 голосов
/ 23 февраля 2019

Попробуйте заменить подзапрос:

(     
  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)
...