2017-08-03 77 views
0

可以存儲多個執行計劃一個SQL程序取決於使用parementers?我的意思是我有一個SQL過程。有兩種調用這個程序(一些輸入參數留NULL)的一些典型的模式,我不想再計劃重新計算每一個電話。多個執行計劃存儲過程取決於所使用的參數

+0

不,你不能存儲多個執行計劃,一個存儲過程調用。 –

+0

有人請糾正我,如果我錯了,但它會在每次重新計算?我相信,這就是參數嗅探的發生過程。您將不得不使用RECOMPILE指定重新計算。如果您知道最常用的參數,你可以在之前的辦公時間作業,以便它是計劃,緩存運行此。 – Leonidas199x

回答

1

答案是的,您可以根據輸入參數爲單個存儲過程制定多個執行計劃。這被稱爲參數嗅探。

如果沒有產生足夠好的計劃,該程序的所有調用表現良好的一組參數,一個選擇是使用優化提示:

OPTIMIZE FOR (@variable_name { UNKNOWN | = literal_constant } [ , ...n ]) 

這將避免使用的做法,需要爲所有調用重新編譯proc。

1

你可以寫一些SP,每一個案件,然後從你的主SP稱他們爲有條件呼叫:

create proc... 
if @param1 is null exec sp_1 @param2, param3 

但是,如果你有太多的情況下,這不是一個很好的解決方法。

在這種情況下,你可以實現你的查詢作爲動態代碼只能與不爲空參數構造它,在這裏看到的例子:Implementing search_orders with a Parameterised Query by Erland sommarskog,代碼如下。

這樣的查詢不重新編譯每一次,但會有正是這麼多的計劃儘可能多的不同查詢可以構建組合不僅沒有空參數(你想要的東西,)

CREATE PROCEDURE search_orders_1         -- 1 
       @orderid  int   = NULL,     -- 2 
       @fromdate datetime  = NULL,     -- 3 
       @todate  datetime  = NULL,     -- 4 
       @minprice money  = NULL,     -- 5 
       @maxprice money  = NULL,     -- 6 
       @custid  nchar(5)  = NULL,     -- 7 
       @custname nvarchar(40) = NULL,     -- 8 
       @city  nvarchar(15) = NULL,     -- 9 
       @region  nvarchar(15) = NULL,     -- 10 
       @country  nvarchar(15) = NULL,     -- 11 
       @prodid  int   = NULL,     -- 12 
       @prodname nvarchar(40) = NULL,     -- 13 
       @employeestr varchar(MAX) = NULL,     -- 14 
       @employeetbl intlist_tbltype READONLY,   -- 15 
       @debug  bit   = 0 AS     -- 16 
                    -- 17 
DECLARE @sql  nvarchar(MAX),         -- 18 
     @paramlist nvarchar(4000),        -- 19 
     @nl   char(2) = char(13) + char(10)     -- 20 
                    -- 21 
SELECT @sql =              -- 22 
    'SELECT o.OrderID, o.OrderDate, od.UnitPrice, od.Quantity,  -- 23 
      c.CustomerID, c.CompanyName, c.Address, c.City,  -- 24 
      c.Region, c.PostalCode, c.Country, c.Phone,   -- 25 
      p.ProductID, p.ProductName, p.UnitsInStock,   -- 26 
      p.UnitsOnOrder, o.EmployeeID       -- 27 
    FROM dbo.Orders o           -- 28 
    JOIN dbo.[Order Details] od ON o.OrderID = od.OrderID  -- 29 
    JOIN dbo.Customers c ON o.CustomerID = c.CustomerID   -- 30 
    JOIN dbo.Products p ON p.ProductID = od.ProductID   -- 31 
    WHERE 1 = 1' + @nl           -- 32 
                    -- 33 
IF @orderid IS NOT NULL           -- 34 
    SELECT @sql += ' AND o.OrderID = @orderid' +     -- 35 
        ' AND od.OrderID = @orderid' + @nl    -- 36 
                    -- 37 
IF @fromdate IS NOT NULL           -- 38 
    SELECT @sql += ' AND o.OrderDate >= @fromdate' + @nl   -- 39 
                    -- 40 
IF @todate IS NOT NULL            -- 41 
    SELECT @sql += ' AND o.OrderDate <= @todate' + @nl    -- 42 
                    -- 43 
IF @minprice IS NOT NULL           -- 44 
    SELECT @sql += ' AND od.UnitPrice >= @minprice' + @nl   -- 45 
                    -- 46 
IF @maxprice IS NOT NULL           -- 47 
    SELECT @sql += ' AND od.UnitPrice <= @maxprice' + @nl   -- 48 
                    -- 49 
IF @custid IS NOT NULL            -- 50 
    SELECT @sql += ' AND o.CustomerID = @custid' +     -- 51 
        ' AND c.CustomerID = @custid' + @nl    -- 52 
                    -- 53 
IF @custname IS NOT NULL           -- 54 
    SELECT @sql += ' AND c.CompanyName LIKE @custname + ''%''' + @nl -- 55 
                    -- 56 
IF @city IS NOT NULL            -- 57 
    SELECT @sql += ' AND c.City = @city' + @nl      -- 58 
                    -- 59 
IF @region IS NOT NULL            -- 60 
    SELECT @sql += ' AND c.Region = @region' + @nl     -- 61 
                    -- 62 
IF @country IS NOT NULL           -- 63 
    SELECT @sql += ' AND c.Country = @country' + @nl    -- 64 
                    -- 65 
IF @prodid IS NOT NULL            -- 66 
    SELECT @sql += ' AND od.ProductID = @prodid' +     -- 67 
        ' AND p.ProductID = @prodid' + @nl    -- 68 
                    -- 69 
IF @prodname IS NOT NULL           --70 
    SELECT @sql += ' AND p.ProductName LIKE @prodname + ''%''' + @nl-- 71 
                    -- 72 
IF @employeestr IS NOT NULL          -- 73 
    SELECT @sql += ' AND o.EmployeeID IN' +       -- 74 
        ' (SELECT number FROM dbo.intlist_to_tbl(@employeestr))' + @nl 
                    -- 76 
IF EXISTS (SELECT * FROM @employeetbl)        -- 77 
    SELECT @sql += ' AND o.EmployeeID IN (SELECT val FROM @employeetbl)' + @nl 
                    -- 79 
SELECT @sql += ' ORDER BY o.OrderID' + @nl       -- 80 
                    -- 81 
IF @debug = 1              -- 82 
    PRINT @sql              -- 83 
                    -- 84 
SELECT @paramlist = '@orderid  int,        -- 85 
        @fromdate datetime,      -- 86 
        @todate  datetime,      -- 87 
        @minprice money,       -- 88 
        @maxprice money,       -- 89 
        @custid  nchar(5),      -- 90 
        @custname nvarchar(40),     -- 91 
        @city  nvarchar(15),     -- 92 
        @region  nvarchar(15),     -- 93 
        @country  nvarchar(15),     -- 94 
        @prodid  int,        -- 95 
        @prodname nvarchar(40),     -- 96 
        @employeestr varchar(MAX),     -- 97 
        @employeetbl intlist_tbltype READONLY'  -- 98 
                    -- 99 
EXEC sp_executesql @sql, @paramlist,        -- 100 
        @orderid, @fromdate, @todate, @minprice,  -- 101 
        @maxprice, @custid, @custname, @city, @region, -- 102 
        @country, @prodid, @prodname, @employeestr, @employeetbl 
相關問題