sql - 为什么 SQL 评估的 WHERE 子句为 False?

标签 sql sql-server sql-server-2008

我在 SQL (2008) 中有一个查询,如果我在 WHERE 语句中包含一个不会影响结果的子句,我无法理解为什么要花这么长时间来评估。以下是查询示例:

declare @includeAll bit = 0;

    SELECT
        Id
        ,Name
        ,Total
    FROM
        MyTable
    WHERE
        @includeAll = 1 OR Id = 3926

显然,在这种情况下,@includeAll = 1 将评估为 false;然而,包括这一点会增加查询时间,就好像它总是正确的一样。无论有没有该子句,我得到的结果都是正确的:我只得到 Id = 3926 的 1 个条目,但是(在我的实际查询中)包括该行会将查询时间从 < 0 秒增加到大约 7 分钟...因此,它似乎正在运行查询,就好像该语句是正确的一样,即使事实并非如此,但仍然返回正确的结果。

任何可以阐明原因的说明都会有所帮助。另外,如果您有解决此问题的建议,我会接受。我想要一个像这样的子句,这样我就可以在存储过程中包含一个参数,该参数将使其忽略它拥有的 Id 并返回所有结果(如果设置为 true),但我不能允许这影响仅尝试获取一条记录时的性能。

最佳答案

您需要查看查询计划才能确定,但​​使用 OR 通常会使其在某些 DBMS 中像这样扫描。

另外,请阅读 @Bogdan Sahlean 的回复,了解发生这种情况的一些重要细节。

这可能行不通,但如果您需要坚持使用直接 SQL,您可以尝试类似的方法:

SELECT
    Id
   ,Name
   ,Total
FROM
    MyTable
WHERE Id = 3926
UNION ALL
SELECT
    Id
   ,Name
   ,Total
FROM
    MyTable
WHERE Id <> 3926
AND   @includeAll = 1

如果您使用存储过程,则可以有条件地以任一方式运行 SQL,这可能更有效。

类似于:

if @includeAll = 0 then
    SELECT
        Id
       ,Name
       ,Total
    FROM
        MyTable
    WHERE Id = 3926
else
    SELECT
        Id
       ,Name
       ,Total
    FROM
        MyTable

关于sql - 为什么 SQL 评估的 WHERE 子句为 False?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23742252/

相关文章:

c# - 数据库第一种方法中缺少 Entity Framework 导航属性

SQL Server 似乎四舍五入不正确

mysql - 从触发器中获取良好的成功通知消息

c# - 为什么试图用存储过程保存一个 URL 只会插入一个点?

sql-server - 分析服务连接被远程主机关闭(Azure SQL 数据库)

mysql - 尝试消除重复行的 SQL 查询

c# - 如何连接到本地SQL数据库?

sql - 如何查询多个链接服务器?

sql-server - Microsoft SQL 代理作业中的 sp_send_dbmail 错误

sql-server-2005 - "Type DATE is not a defined system type."