我创建了一个查询大量数据的存储过程,但该查询仅针对一个国家/地区的2个客户。
我只是想知道是否可以将多个CustomerID添加到OPTIMIZE FOR语句中,例如
option (OPTIMIZE FOR (@CountryId = 122, @CustomerId = 321654, @CustomerId 78954))
上面的例子没有编译:
为变量" @ CustomerId"多次指定编译时文字值。在一个或多个OPTIMIZE FOR子句中。
答案 0 :(得分:0)
您可以做的一件事是根据参数值调用不同的过程,每个过程将计算自己的统计数据,例如在你的程序IF @CustomerId = 321654 EXEC proc_321654 ELSE EXEC proc_78954。像这样:
CREATE PROCEDURE innerProc_78954
AS
BEGIN
SELECT ...
WHERE CustomerId = 78954
END
GO
CREATE PROCEDURE innerProc_321654
AS
BEGIN
SELECT ...
WHERE CustomerId = 321654
END
GO
CREATE PROCEDURE outerProc
@CustomerId INT
AS
BEGIN
IF @CustomerId = 321654
EXEC innerProc_321654
ELSE
EXEC innerProc_78954
END
GO
因此innerProc_78954和innerProc_321654基本上是重复的,但每个都只使用特定参数调用,因此每个参数都有针对其自身参数优化的统计信息。
这是一个简单的示例,其中包含示例数据:
-- Create test data - 10,000 rows for CustomerId 1, 100 rows for CustomerId 2
CREATE TABLE #Orders (CustomerId INT, OrderDate DATETIME)
DECLARE @c1 INT = 0
DECLARE @c2 INT = 0
WHILE @c1 < 100
BEGIN
SET @c2 = 0
WHILE @c2 < 100
BEGIN
INSERT INTO #Orders (CustomerId, OrderDate) VALUES (1, GETDATE() - 100)
SET @c2 += 1
END
INSERT INTO #Orders (CustomerId, OrderDate) VALUES (2, GETDATE() - 100)
SET @c1 += 1
END
GO
-- The procedure optimized for CustomerId = 1
CREATE PROCEDURE #proc1
@CustomerId INT
AS
SELECT * FROM #Orders WHERE CustomerId = @CustomerId
GO
-- The procedure optimized for CustomerId = 2
CREATE PROCEDURE #proc2
@CustomerId INT
AS
SELECT * FROM #Orders WHERE CustomerId = @CustomerId
GO
-- The outer procedure to call from your client application.
CREATE PROCEDURE #procAll
@CustomerId INT
AS
IF @CustomerId = 1
EXEC #proc1 1
ELSE
EXEC #proc2 2
GO
-- Run your outer procedure and verify the actual # of rows matches the
-- estimated # of rows for each parameter.
EXEC #procAll 1
EXEC #procAll 2
-- Now run the inner procedures with the incorrect parameters - note that the
-- estimated # of rows does not match the actual # of rows, demonstrating that
-- statistics were optimized for the other parameter.
EXEC #proc1 2
EXEC #proc2 1