使用:MS SQL SERVER 2008R2至2016
我有一个存储过程(下面的简化版本),它返回按几个参数中的任何一个过滤的产品列表。我返回的数据仅来自主表(Products),但可以通过任何其他表中的交叉引用数据进行过滤。
下面的代码将起作用,但是如果没有为连接提供参数,则效率明智,服务器仍然会获得链接到该表的效率,即使数据意味着不需要过滤。
我可以在动态sql中构建它,并根据参数添加连接,但我尽量避免动态 - 总是难以维护。
有没有人有他们使用过或想过的更好的解决方案?我确实有几个工作选项,但看看代码我觉得必须有更好的选择。
非常感谢。
CREATE PROC FilteredProducts
@CatalogueID INT = NULL
, @ManufacturerID INT = NULL
, @BrandID INT = NULL
AS
BEGIN
SELECT Products.*
FROM Products P
JOIN Catalogue C ON P.ID = C.ProductID
AND (@CatalogueID IS NULL
OR C.ID = @CatalogueID
)
JOIN Manufacturers M ON P.ID = M.Products_ID
AND (@ManufacturerID IS NULL
OR M.ID = @ManufacturerID
)
JOIN Brands B ON P.ID = B.Products_ID
AND (@BrandID IS NULL
OR B.ID = @BrandID
)
END
编辑:
添加了代码示例
DECLARE @InstockOnly AS BIT = 0
SELECT AP.*
FROM ABCD.AllowedProducts AP
JOIN ABCD.DatabaseStockLevels DSL ON DSL.ProductGUID = AP.ProductGUID
AND (@InstockOnly = 0
OR DSL.StockLevel > 0
)
OPTION (RECOMPILE)
当执行上面的代码以按库存级别进行特定过滤时,实际执行计划显示尽管InstockOnly = 0,但仍会评估连接。尽管我的数据是1对1关系,但SQL Server不知道,所以如果存在1对多关系,则执行连接。虽然选项(重新编译)确实简化了连接,但我正在寻找一种完全删除连接的方法。