有效处理WHERE子句中多个可选约束(Efficiently Handling Multiple O

2019-07-29 20:48发布

这是一个续集一定程度的慢检查存在的 。 Alex的建议可行,成功地避免了重复的代码,但我还是结束了第二个问题。 考虑下面的例子(从AlexKuznetsov)。 在这里面,我有两个分支处理1个contraint。 如果我有2度可选的限制,我将结束了4个分公司。 基本上,分支的数量与约束的数量呈指数增加。

在另一方面,如果我用一个多语句表值函数或以其它方式使用临时表,SQL查询优化器不能够帮助我,让事情变得缓慢。 我有些怀疑的动态SQL(我听说它是​​缓慢的,太)。

任何人都可以提供关于如何增加更多的限制建议,但不会增加很多的if语句?

注:我以前尝试过链接x is null or inpo = @inpo在一起,但是这是非常缓慢的。 请记住,虽然inpo = @inpo测试可以通过某种索引的黑魔法的处理,在法律上无效测试结束了在表中的每一行进行评估。

IF @inpo IS NULL BEGIN
  SELECT a,b,c 
    FROM dbo.ReuseMyQuery(@i1)
    ORDER BY c;
END ELSE BEGIN
  SELECT a,b,c 
    FROM dbo.ReuseMyQuery(@i1)
    WHERE inpo = @inpo
    ORDER BY c;
END

变化二:2个约束:

IF @inpo IS NULL BEGIN      
    IF @inpo2 IS NULL BEGIN
        SELECT a,b,c 
        FROM dbo.ReuseMyQuery(@i1)
        ORDER BY c;
    END ELSE BEGIN
        SELECT a,b,c 
        FROM dbo.ReuseMyQuery(@i1)
        WHERE inpo2 = @inpo2
        ORDER BY c;
    END
END ELSE BEGIN
    IF @inpo2 IS NULL BEGIN
        SELECT a,b,c 
        FROM dbo.ReuseMyQuery(@i1)
        WHERE inpo = @inpo
        ORDER BY c;
    END ELSE BEGIN
        SELECT a,b,c 
        FROM dbo.ReuseMyQuery(@i1)
        WHERE inpo = @inpo AND
              inpo2 = @inpo2
        ORDER BY c;
    END
END

Answer 1:

这是最好的参考: http://www.sommarskog.se/dyn-search-2005.html



Answer 2:

在这种情况下,我使用sp_executesql作为厄兰的文章中描述: 使用sp_executesql无论何时使用动态SQL,没有权限可能是一个问题,所以我有一个单元测试真正的网络账号,我补充一点,考虑到实际作用,我冒充用每当我测试动态SQL,如这里所描述的真实账户: 数据库单元测试:模拟



Answer 3:

这里有一个粗略的例子。 根据修改,如果你想在WHERE子句中的LIKE语句“打头”或“包含”或在您的查询的精确匹配。

CREATE PROCEDURE dbo.test
@name       AS VARCHAR(50) = NULL,
@address1       AS VARCHAR(50) = NULL,
@address2       AS VARCHAR(50) = NULL,
@city       AS VARCHAR(50) = NULL,
@state      AS VARCHAR(50) = NULL,
@zip_code       AS VARCHAR(50) = NULL
AS

BEGIN

SELECT  [name],
            address1,
            address2,
            city,
            state,
            zip_code
FROM    my_table
WHERE   ([name] LIKE @name + '%' OR @name IS NULL)
            AND (address1 LIKE @address1 + '%' OR @address1 IS NULL)
            AND (address2 LIKE @address2 + '%' OR @address2 IS NULL)
            AND (city LIKE @city + '%' OR @city IS NULL)
            AND (state LIKE @state + '%' OR @state IS NULL)
            AND (zip_code LIKE @zip_code + '%' OR @zip_code IS NULL)
ORDER BY    [name]
END
GO


Answer 4:

Select blah from foo    
Where (@inpo1 is null or @inpo1 = inpo1)
and (@inpo2 is null or @inpo2 = inpo2)

显然,这是太慢了。 有趣。

你有没有考虑代码生成? 有很多重复冗长的查询只是一个问题,如果它直接维持。



Answer 5:

我知道你的问题可能是纯学术性的,但如果你有真正的使用案例你有没有考虑只对最常见的情况,提供优化的查询?



文章来源: Efficiently Handling Multiple Optional Constraints in Where Clause