現在我有類似的東西:
CREATE PROCEDURE [dbo].[sp_GetFilteredInformation]
@pItem nvarchar(max) = NULL,
@pCity nvarchar(max) = NULL,
@pSerialN nvarchar(max) = NULL,
@pPromise datetime = NULL,
@pSalesOrder nvarchar(max) = NULL,
@pLineNumber int = NULL
DECLARE @vQuery nvarchar(max)
IF (@pItem IS NOT NULL)
BEGIN
SET @vQuery = 'AND ITEM LIKE '' @pItem '''
END
IF (@pCity IS NOT NULL)
BEGIN
SET @vQuery = 'AND CITY LIKE '' @pCity '''
END
......等等,所以最后我會有
SELECT *
FROM TABLE
WHERE 1 = 1 @vQuery
我認為這會奏效,但對我來說似乎沒有效率。有沒有辦法優化這個程序并使用多個引數過濾資訊,其中一些引數為空?
uj5u.com熱心網友回復:
優化通用過濾器的唯一方法是在 SQL 動態查詢中決議過濾器的所有專案和條件。
為此,您需要有 2 個 XML 引數:
- 列出要到達的列,格式為:date_begintown
- 另一個具有資料型別和值,例如: <val @type=date>2021-09-31<val @type=string>Paris
然后使用這兩個僅包含搜索值列的字串,您可以構建一個查詢,該查詢將具有特定且可優化的 WHERE 謂詞...
uj5u.com熱心網友回復:
執行這種型別的廚房水槽查詢的最有效方法實際上就是您現在的做法,只是您應該正確地引數化每個過濾器。
這是因為每個可能的過濾器組合都會快取一個計劃。這意味著無論何時再次使用該過濾器組合,即使使用不同的值,也將使用快取計劃。
而如果您使用OPTION(RECOMPILE),則每次運行都會生成一個新計劃。而且OPTION(OPTIMIZE FOR UNKNOWN)通常只會為您提供一個不太好的總體計劃。
所以你用 引數化它sp_executesql,像這樣
CREATE PROCEDURE [dbo].[sp_GetFilteredInformation]
@pItem nvarchar(max) = NULL,
@pCity nvarchar(max) = NULL,
@pSerialN nvarchar(max) = NULL,
@pPromise datetime = NULL,
@pSalesOrder nvarchar(max) = NULL,
@pLineNumber int = NULL
DECLARE @vQuery nvarchar(max) = '
SELECT *
FROM YourTable
WHERE 1=1
';
IF (@pItem IS NOT NULL)
SET @vQuery = 'AND ITEM LIKE @pItem
';
IF (@pCity IS NOT NULL)
SET @vQuery = 'AND CITY LIKE @pCity
';
-- etc
-- for testing you can use PRINT @vQuery
EXEC sp_executesql
@vQuery,
N'@pItem nvarchar(max),
@pCity nvarchar(max),
@pSerialN nvarchar(max),
@pPromise datetime,
@pSalesOrder nvarchar(max),
@pLineNumber int',
@pItem = @pItem,
@pCity = @pCity,
@pSerialN = @pSerialN,
@pPromise = @pPromise,
@pSalesOrder = @pSalesOrder,
@pLineNumber = @pLineNumber;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/313297.html
標籤:sql sql-server 数据库 查询语句
