Кто-то может объяснить лучше, чем я, почему это намного быстрее.Опыт подсказывает мне, когда у вас есть куча запросов, которые вместе работают медленно, но должны быть быстрыми в отдельных частях, тогда стоит попробовать временную таблицу.
Это намного быстрее
ALTER PROCEDURE LockBranches
-- Add the parameters for the stored procedure here
@count INT,
@lockedOn DATETIME,
@unlockOn DATETIME,
@lockedBy UNIQUEIDENTIFIER
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
--Create Temp Table
SELECT SpicieBranches.BranchID AS BranchID, SUM(X.SuitableProbes) AS SuitableProbes
INTO #BranchSuitableProbeCount
FROM SpicieBranches
INNER JOIN Probes AS P ON P.SpicieID = SpicieBranches.SpicieID
INNER JOIN
(
SELECT P.ID, 1 AS SuitableProbes
FROM Probes AS P
INNER JOIN Results AS R ON P.ID = R.ProbeID
GROUP BY P.ID
HAVING COUNT(R.ID) > 0
) AS X ON P.ID = X.ID
GROUP BY SpicieBranches.BranchID
UPDATE B SET
B.LockedBy = @lockedBy,
B.LockedOn = @lockedOn,
B.UnlockOn = @unlockOn,
B.Complete = 1
FROM
(
SELECT TOP (@count) Branches.LockedBy, Branches.LockedOn, Branches.UnlockOn, Branches.Complete
FROM Objectives
INNER JOIN Generations ON Generations.ObjectiveID = Objectives.ID
INNER JOIN Branches ON Branches.GenerationID = Generations.ID
INNER JOIN #BranchSuitableProbeCount ON Branches.ID = #BranchSuitableProbeCount.BranchID
WHERE
(Objectives.Active = 1)
AND (Branches.Sealed = 0)
AND (Branches.GenerationNo < Objectives.BranchGenerations)
AND (Branches.LockedBy IS NULL OR DATEDIFF(SECOND, Branches.UnlockOn, GETDATE()) > 0)
AND (Branches.Complete = 1 OR #BranchSuitableProbeCount.SuitableProbes = Objectives.BranchSize * Objectives.EstimateCount * Objectives.ProbeCount)
) AS B
END
Это намного быстрее при среднем времени выполнения 54 мс по сравнению с 6 секундами с исходным.
РЕДАКТИРОВАТЬ
Посмотрел и соединил мои идеи с идеями RBarryYoungрешение.Если вы используете следующую команду для создания временной таблицы
SELECT SB.BranchID AS BranchID, COUNT(*) AS SuitableProbes
INTO #BranchSuitableProbeCount
FROM SpicieBranches AS SB
INNER JOIN Probes AS P ON P.SpicieID = SB.SpicieID
WHERE EXISTS(SELECT * FROM Results AS R WHERE R.ProbeID = P.ID)
GROUP BY SB.BranchID
, вы можете уменьшить ее до 15 мс, что в 400 раз лучше, чем мы начали.Просмотр плана выполнения показывает, что на временной таблице происходит сканирование таблицы.Обычно вы избегаете сканирования таблиц настолько хорошо, насколько это возможно, но для 128 строк (в данном случае) это происходит быстрее, чем раньше.