Я занимаюсь подкачкой с SQL Server, и я бы хотел избежать дублирования, посчитав общее количество результатов как часть моего частичного набора результатов, а не получая этот набор результатов, а затем выполнив отдельный запрос, чтобы получить счетчик впоследствии. Однако проблема заключается в увеличении времени выполнения. Например, если я проверю с SET STATISTICS TIME ON
, это:Использование COUNT() внутри CTE дороже, чем вне CTE?
WITH PagedResults AS (
SELECT
ROW_NUMBER() OVER (ORDER BY AggregateId ASC) AS RowNumber,
COUNT(PK_MatrixItemId) OVER() AS TotalRowCount,
*
FROM [MyTable] myTbl WITH(NOLOCK)
)
SELECT * FROM PagedResults
WHERE RowNumber BETWEEN 3 AND 4810
... или это (чей план выполнения идентичен):
SELECT * FROM (
SELECT TOP (4813)
ROW_NUMBER() OVER (ORDER BY AggregateId ASC) AS RowNumber,
COUNT(PK_MatrixItemId) OVER() AS TotalRowCount,
*
FROM [MyTable] myTbl WITH(NOLOCK)
) PagedResults
WHERE PagedResults.RowNumber BETWEEN 3 AND 4810
... кажется, в среднем времени процессора (все запросы суммируется) от 1,5 до 2 раз больше, чем это:
SELECT * FROM (
SELECT TOP (4813)
ROW_NUMBER() OVER (ORDER BY AggregateId ASC) AS RowNumber,
*
FROM [MyTable] myTbl WITH(NOLOCK)
) PagedResults
WHERE PagedResults.RowNumber BETWEEN 3 AND 4810
SELECT COUNT(*) FROM [MyTable] myTbl WITH(NOLOCK)
Очевидно, что я бы предпочел использовать бывший, чем последний, потому что последний избыточно повторяет положение FROM
(и вес ould повторить любые WHERE
предложения, если бы у меня были какие-либо), но время его выполнения намного лучше, я действительно должен его использовать. Есть ли способ, которым я могу полностью сократить время исполнения первого?
Что вы получили от плана исполнения? должно быть полезно понять ваши варианты и дать некоторый намек на объяснение. – Paolo
Это довольно сложно сказать, потому что планы выполнения отличаются друг от друга, но, насколько я вижу, план выполнения первого содержит этап «Вложенные петли», который соединяет колонку count с остальными, что имеет значительные накладные расходы. – Jez