Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server WHERE子句未按逻辑顺序进行筛选_Sql Server_Sql Server 2008_Tsql_Isnull - Fatal编程技术网

Sql server WHERE子句未按逻辑顺序进行筛选

Sql server WHERE子句未按逻辑顺序进行筛选,sql-server,sql-server-2008,tsql,isnull,Sql Server,Sql Server 2008,Tsql,Isnull,我正在编写一个通用搜索存储过程,以基于用户可以在UI中选择的许多过滤器在表中进行搜索(使用MS-SQL 2008) 以下是简化版本: CREATE PROCEDURE SearchAll @FirstName NVARCHAR(MAX) = NULL, @LastName NVARCHAR(MAX) = NULL, @Age INT = NULL AS SELECT * FROM persons WHERE (@FirstNa

我正在编写一个通用搜索存储过程,以基于用户可以在UI中选择的许多过滤器在表中进行搜索(使用MS-SQL 2008)

以下是简化版本:

CREATE PROCEDURE SearchAll
    @FirstName NVARCHAR(MAX) = NULL,
    @LastName NVARCHAR(MAX) = NULL,
    @Age INT = NULL
AS
    SELECT * 
    FROM persons 
    WHERE 
        (@FirstName IS NULL OR FirstName = @firstname)
        AND (@LastName IS NULL OR LastName = @LastName)
        AND (@Age IS NULL OR Age = @Age)
似乎如果我将NULL传递给@Age,就不会有性能成本。但是,当我使用大量数据进行测试时,我会损失大量性能

以下是逻辑上相同但实际情况却大不相同的查询:

DECLARE @FirstName NVARCHAR(MAX) = NULL
DECLARE @Age INT = 23
------------First slow------------
SELECT * 
FROM persons 
WHERE 
    (@FirstName IS NULL OR FirstName = @firstname)
    AND (@Age IS NULL OR Age = @Age)
------------Very fast------------
SELECT * 
FROM persons 
WHERE 
    Age = @Age
有没有漏掉一点

我知道SQL引擎会找到索引的最佳匹配,而且。。。(在运行查询之前),但很明显:
@FirstName为NULL
,不需要分析任何内容


我还测试了查询中的
ISNULL
函数(结果相同)。

包含
@变量为null或@variable=column
构造的查询会导致性能灾难。这是因为SQL计划是为变量的任何值创建的。对于该主题的详细讨论,问题和可能的解决方案请参见

前面已经提到的问题是,将构建查询计划以处理变量的任何值。您可以通过仅使用所需参数构建查询来规避此问题,如下所示:

CREATE PROCEDURE SearchAll
    @FirstName NVARCHAR(MAX) = NULL,
    @LastName NVARCHAR(MAX) = NULL,
    @Age INT = NULL
AS
BEGIN
    DECLARE @sql NVARCHAR(MAX), @has_where BIT
    SELECT @has_where = 0, @sql = 'SELECT * FROM persons '

    IF @FirstName IS NOT NULL
        SELECT @sql = @sql + 'WHERE FirstName = ''' + @FirstName + '''', @has_where = 1
    IF @LastName IS NOT NULL
        SELECT @sql = @sql + CASE WHEN @has_where = 0 THEN 'WHERE ' ELSE 'AND ' END + 'LastName = ''' + @LastName + '''', @has_where = 1
    IF @Age IS NOT NULL
        SELECT @sql = @sql + CASE WHEN @has_where = 0 THEN 'WHERE ' ELSE 'AND ' END + 'Age = ' + CAST(@Age AS VARCHAR), @has_where = 1

    EXEC sp_executesql @sql
END

在WHERE子句中为我的变量使用“CASE-WHEN”如何?您的问题是访问路径,而不是运算符短路。这个案子毫无帮助。