SET @SQL = 'SELECT * FROM Comment with(nolock) WHERE 1=1

And (@ProjectIds Is Null or ProjectId = @ProjectIds)

And (@Scores is null or Score =@Scores)'

印象中记得,以前在做Oracle开发时,这种写法是会导致全表扫描的,用不上索引,不知道Sql Server里是否也是一样呢,于是做一个简单的测试

1、建立测试用的表结构和索引:

CREATE TABLE aaa(id int IDENTITY, NAME VARCHAR(12), age INT)

go

CREATE INDEX idx_age ON aaa (age)

GO

2、插入1万条测试数据:

DECLARE @i INT;

SET @i=0;

WHILE @i<10000

BEGIN

INSERT INTO aaa (name, age)VALUES(CAST(@i AS VARCHAR), @i)

SET @i=@i+1;

END

GO

3、先开启执行计划显示:

在SQL Server Management Studio的查询窗口里,右击窗口任意位置,选择“包含实际的执行计划”:

4、开始测试,用下面的SQL进行测试:

DECLARE @i INT;

SET @i=100

SELECT * FROM aaa WHERE (@i IS NULL OR age = @i)

SELECT * FROM aaa WHERE (age = @i OR @i IS NULL)

SELECT * FROM aaa WHERE age=isnull(@i, age)

SELECT * FROM aaa WHERE age = @i

测试结果如下:

可以看到,即使@i有值,不管@i IS NULL是放在前面还是放在后面,都无法用到age的索引,另外age=ISNULL(@i,age)也用不上索引

最终结论,SQL Server跟ORACLE一样,如果条件里加了 变量 IS NULL,都会导致全表扫描。

建议SQL改成:

DECLARE @i INT;

SET @i=100

DECLARE @sql NVARCHAR(MAX)

SET @sql = 'SELECT * FROM aaa'

IF @i IS NOT NULL

SET @sql = @sql + ' WHERE age = @i'

EXEC sp_executesql @sql, N'@i int', @i

当然,如果只有一个条件,可以设计成2条SQL,比如:

DECLARE @i INT;

SET @i=100

IF @i IS NOT NULL

SELECT * FROM aaa WHERE age = @i

ELSE

SELECT * FROM aaa

但是,如果条件多了,SQL数目也变得更多,所以建议用EXEC的方案

where is null mysql_SQL中WHERE变量IS NULL条件导致全表扫描问题的解决方法相关推荐

  1. ios系统微信浏览器、safari浏览器中h5页面上拉下滑导致悬浮层脱离窗口的解决方法

    ios系统微信浏览器.safari浏览器中h5页面上拉下滑导致悬浮层脱离窗口的解决方法 参考文章: (1)ios系统微信浏览器.safari浏览器中h5页面上拉下滑导致悬浮层脱离窗口的解决方法 (2) ...

  2. SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析

    在SQL SERVER的查询语句中使用OR是否会导致不走索引查找(Index Seek)或索引失效(堆表走全表扫描 (Table Scan).聚集索引表走聚集索引扫描(Clustered Index ...

  3. bashrc文件中环境变量配置错误,导致linux命令无法正常使用的解决方案

    分析原因 bashrc文件中环境变量配置错误,导致linux无法正常使用. 其实解决问题的方法很简单:把你在bashrc文件中写错的东西注释掉或者改写正确即可. 可是此时图形界面登陆不了,vim用不了 ...

  4. js 定时器(setTimeout/setInterval)出现变量未定义(xxx is not defined) 的解决方法

    js 定时器(setTimeout/setInterval)出现变量未定义(xxx is not defined) 的解决方法 参考文章: (1)js 定时器(setTimeout/setInterv ...

  5. VMware vSphere Client中启动虚拟机提示No boot filename received/Operating System not found解决方法

    VMware vSphere Client中启动虚拟机提示No boot filename received/Operating System not found解决方法 参考文章: (1)VMwar ...

  6. oracle中“ORA-00060: 等待资源时检测到死锁” 或存储过程编译卡死 解决方法

    oracle中"ORA-00060: 等待资源时检测到死锁" 或存储过程编译卡死 解决方法 参考文章: (1)oracle中"ORA-00060: 等待资源时检测到死锁& ...

  7. Win7x64中使用VS调试WEB项目报“ORA-06413: 连接未打开”错误解决方法

    错误描述 普通Web项目,Web项目在32位系统上跑的好好的,一点问题没有. 使用VS内置的开发服务器调试,页面能正常启动,但一连接数据库就报"ORA-06413: 连接未打开"错 ...

  8. Proxmox VE中出现TASK ERROR: command ‘apt-get update‘ failed: exit code 100的解决方法

    Proxmox VE中出现TASK ERROR: command 'apt-get update' failed: exit code 100的解决方法 参考文章: (1)Proxmox VE中出现T ...

  9. iOS中 H5的input输入框focus()无法自动拉起键盘(解决方法)

    iOS中 H5的input输入框focus()无法自动拉起键盘(解决方法) 参考文章: (1)iOS中 H5的input输入框focus()无法自动拉起键盘(解决方法) (2)https://www. ...

最新文章

  1. 【Three.js】关于Three.js的辅助库ststs.js报错的解决方案
  2. mysql开启binlog启动慢_mysql配置开启binlog与慢查询日志功能
  3. ionic4监听返回事件 AppMinimize navController
  4. 《C++ Primer》7.5.2节练习
  5. web浏览器_Web上的分享(Share)API
  6. 接口测试工具--apipost脚本讲解
  7. MySQL索引(1)
  8. linux中安装pip镜像怎么设置_linux服务器怎么安装pip?
  9. 学习和研究下unity3d的四元数 Quaternion
  10. linux 输入--输出--重定向 stdin/stdout/stderr
  11. 计算机网络及电子邮件的原理,全国2006年4月全国自考计算机网络基本原理真题及答案..doc...
  12. 天网防火墙技术白皮书
  13. 如何将大硬盘对拷到小硬盘
  14. 基于spss的聚类分析(Cluster analysis)
  15. 计算机c盘无法扩展,C盘不够大怎么办 怎么扩展C盘容量合并硬盘分区
  16. IDEA打字冒火花教程
  17. jquery方法之append()与appendto()
  18. linux中mysql客户端命令行连接不了 docker 创建的mysql
  19. match2(双周赛)
  20. padding oracle attack相关之padding oracle attack

热门文章

  1. zabbix企业应用之监控docker容器资源情况
  2. 4. 星际争霸之php设计模式--工厂方法模式
  3. 【代码收集】提前载入贴图
  4. 初次接触GWT,知识点总括
  5. 详解UML中的聚合,关联,泛化等关系
  6. 电力自动化及继电保护实验室规章制度
  7. 这几天惨遭Delphi类型转换折磨,请问怎么把double转成int类型
  8. Angular程序架构
  9. Zookeeper JavaApi 增删改查
  10. mysql连接idea详细教程_idea配置连接数据库的超详细步骤