TL; DR - хранимая процедура, содержащая два запроса на выборку, относящихся к 33 миллионам записей, заняла у меня 45 секунд без выполнения транзакции, 48 секунд с.
Отказ от ответственности: я написал хранимую процедуру в течение примерно 4 часов и натолкнулся на несколько измеримый ответ на этот вопрос (ПРИМЕЧАНИЕ: это не так уж важно!) Пробелы в логике запросов намеренно опущены из-за чувствительности данныхЯ работал с.
Методология: эта процедура была разработана с использованием двух запросов: один выполняет большую часть тяжелой работы, а другой вычисляет одно дополнительное поле самостоятельно, поэтому он не пытается вычислить поле больше, чем нужно.Я разбил его на два этапа:
1) Я написал 2 общих табличных выражения с 1 SQL SELECT во временную таблицу, а затем запросил его снова.Я должен был сделать это, потому что мои требования требовали реализовать пару скалярных функций, которые в противном случае попытались бы запустить функцию на более чем 33 миллионах записей вместо 355.
2) Я прикрепил скалярное значениеФункция ПОСЛЕ первого запроса, чтобы он не пытался просмотреть 30 миллионов записей (если вам интересно, это имело огромное значение).
Запрос: Для читателей я вырезал большую частьзапроса (оператор case).
CREATE PROC GET_PAYMENT_SUMS_BY_CLIENT
AS
--Required for reporting in a specific Business Intelligence later; Optional
SET FMTONLY OFF;
BEGIN TRANSACTION
--Query 1
--This CTE checks over 30 million records
WITH CTE1 AS(
SELECT CASE VARIABLE
--170 case conditions go here
END AS TheType,
Amount,
PK1 FROM TABLE1),
--THIS CTE Pivots the sums to get the data in the style I want it in
CTE2 AS(
SELECT PK1, [PIVOT1], [PIVOT2], [PIVOT3]
FROM
(SELECT * FROM CTE1) AS BaseTable --Alias was just to get it to execute
)
PIVOT(
SUM(Amount)
FOR TheType IN ([PIVOT1], [PIVOT2], [PIVOT3])
) AS PivotTable
)
)
SELECT TABLE2.NAME, CTE2.* INTO #TEMPORARY_TABLE
FROM CTE2
JOIN TABLE2 ON CTE2.PK1 = TABLE2.PK2
--Query 2
--Written to force the function to look at 355 records instead of 33 million
SELECT *, dbo.SCALAR_VALUED_FUNCTION(PK2) FROM #TEMPORARY_TABLE
COMMIT TRANSACTION
Выводы:
С транзакцией - если используется логика транзакции, результирующий запрос из этого набора занимает 48 секунд для обработки более 33 миллионов записей воператор case, содержащий 170 строк, сводит данные по сумме, помещает данные во временную таблицу и присоединяет скалярную функцию ПОСЛЕ первого выполнения запроса.
Без транзакции - если закомментированные строки в коде оставляются закомментированными, все вышеупомянутые шаги выполняются за 45 секунд.Это примерно на 7% быстрее, чем с блоком транзакций: 3/45 = 0,0666 .... ~ 7% быстрее.
Вывод: хотя мои усилия не могут сказать вам, даст ли один и тот же запрос для 10 записей,та же пропорция различий может сказать вам, что это начинает иметь большее значение, когда вы начинаете с более крупными наборами данных и / или более сложными запросами.
У меня есть эта информация, которая послужила цели кому-то там!