Рассмотрим следующий запрос ...TSQL Последняя запись Эффективность Cursor, подзапрос или КТР
SELECT
*
,CAST(
(CurrentSampleDateTime - PreviousSampleDateTime) AS FLOAT
) * 24.0 * 60.0 AS DeltaMinutes
FROM
(
SELECT
C.SampleDateTime AS CurrentSampleDateTime
,C.Location
,C.CurrentValue
,(
SELECT TOP 1
Previous.SampleDateTime
FROM Samples AS Previous
WHERE
Previous.Location = C.Location
AND Previous.SampleDateTime < C.SampleDateTime
ORDER BY Previous.SampleDateTime DESC
) AS PreviousSampleDateTime
FROM Samples AS C
) AS TempResults
Предполагая, что при прочих равных условиях, таких как индексирование и т.д. это наиболее эффективный способ достижения вышеуказанных результатов? Это использует SubQuery для извлечения последней записи?
Будет ли я лучше создавать курсор, который упорядочивает по Location, SampleDateTime и настраивает переменные для CurrentSampleDateTime и PreviousSampleDateTime ..., устанавливая значение Previous to the Current в нижней части цикла while?
Я не очень хорош с CTE, это что-то, что можно было бы сделать более эффективно с помощью CTE? Если да, то как это будет выглядеть?
Скорее всего, мне нужно будет вернуть PreviousValue вместе с предыдущим SampleDateTime, чтобы получить среднее значение из двух. Это влияет на результаты.
Короткий рассказ о том, что является лучшим/наиболее эффективным способом удержания значений предыдущей записи, если вам нужно использовать эти значения в расчетах по текущей записи?
---- UPDATE Следует отметить, что у меня есть кластерный индекс в Location, SampleDateTime, CurrentValue, так что, возможно, именно это влияет на результаты больше всего на свете.
с 5,591,571 записывает мой запрос (тот выше) в среднем занимает 3 минуты и 20 секунд
КТР, что Йоахим Исакссон ниже в среднем занимает 5 минут и 15 секунд.
Возможно, это занимает больше времени, потому что оно не использует кластерный индекс, но использует рябину для соединений?
Я начал тестировать метод курсора, но это уже через 10 минут ... так что не идти дальше.
Я дам ему день или около того, но думаю, что я приму ответ CTE, предоставленный Йоахимом Исакссоном, только потому, что нашел новый метод получения последней строки.
Может ли кто-нибудь согласиться с тем, что это индекс в Location, SampleDateTime, CurrentValue, который ускоряет метод подзапроса?
У меня нет SQL Server 2012, поэтому я не могу протестировать метод LEAD/LAG. Я бы поспорил, что это будет быстрее, чем все, что я пробовал, предполагая, что Microsoft реализовала это эффективно. Вероятно, просто нужно поменять указатель на ссылку памяти в конце каждой строки.
я по крайней мере использовать 'MIN' вместо' ТОП 1 х ... ORDER BY x' (если конструкция не предназначена для сортировки нулевой первый) –
@JoachimIsaksson Но он нуждается в ' MAX' – Lamak
Какую версию SQL Server вы используете? –