评论中提到了一个表的问题,该表包含用于调用 proc 的各种参数,并且执行时间因参数值而异。
如果您能够在参数表中添加两个字段--StartTime DATETIME 和 EndTime DATETIME--那么您可以再创建 7 个 SQL 代理作业并安排它们同时运行。
每个Job的Job Step应该是一样的,并且应该类似如下:
DECLARE @Params TABLE (ParamID INT, Param1 DataType, Param2 DataType, ...);
DECLARE @ParamID INT,
@Param1Variable DataType,
@Param2Variable DataType,
...;
WHILE (1 = 1)
BEGIN
UPDATE TOP (1) param
SET param.StartTime = GETDATE() -- or GETUTCDATE()
OUTPUT INSERTED.ParamID, INSERTED.Param1, INSERTED.Param2, ...
INTO @Params (ParamID, Param1, Param2, ...)
FROM Schema.ParameterTable param
WHERE param.StartTime IS NULL;
IF (@@ROWCOUNT = 0)
BEGIN
BREAK; -- no rows left to process so just exit
END;
SELECT @ParamID = tmp.ParamID,
@Param1Variable = tmp.Param1,
@Param2Variable = tmp.Param2,
FROM @Params tmp;
BEGIN TRY
EXEC Schema.MyProc @Param1Variable, @Param2Variable, ... ;
UPDATE param
SET param.EndTime = GETDATE() -- or GETUTCDATE()
FROM Schema.ParameterTable param
WHERE param.ParamID = @ParamID;
END TRY
BEGIN CATCH
... do something here...
END CATCH;
DELETE FROM @Params; // clear out last set of params
END;
该通用结构应允许 8 个 SQL 作业运行,直到所有参数值集都已执行。它解释了这样一个事实,即某些集合会比其他集合运行得更快,因为每个 Job 只会从队列中选择下一个可用的集合,直到没有剩余集合,此时 Job 将干净地退出。
要考虑添加到上述结构中的两件事:
- 一种将 StartTime 字段重置为 NULL 以便稍后可以重新运行该行的方法
- 一种处理错误的方法(即清理 StartTime 不是 NULL 并且 EndTime 是 NULL 并且 StartTime 和 GETDATE / GETUTCDATE 之间的 DATEDIFF 太多的行。TRY / CATCH 可以通过将 StartTime 设置回 NULL 来实现重新运行,或者为 ErrorTime DATETIME 添加第三个字段,该字段在运行开始时重置为 NULL(与其他 2 个字段一样),但仅在发生错误时设置。这些只是一些想法。