SQL Server - OPTION OPTIMIZE FOR - 2个特定ID

时间:2018-01-24 04:29:13

标签: sql-server query-optimization

我创建了一个查询大量数据的存储过程,但该查询仅针对一个国家/地区的2个客户。

我只是想知道是否可以将多个CustomerID添加到OPTIMIZE FOR语句中,例如

option (OPTIMIZE FOR (@CountryId = 122, @CustomerId = 321654, @CustomerId 78954))

上面的例子没有编译:

为变量" @ CustomerId"多次指定编译时文字值。在一个或多个OPTIMIZE FOR子句中。

1 个答案:

答案 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