where is null mysql_SQL中WHERE变量IS NULL条件导致全表扫描问题的解决方法
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条件导致全表扫描问题的解决方法相关推荐
- ios系统微信浏览器、safari浏览器中h5页面上拉下滑导致悬浮层脱离窗口的解决方法
ios系统微信浏览器.safari浏览器中h5页面上拉下滑导致悬浮层脱离窗口的解决方法 参考文章: (1)ios系统微信浏览器.safari浏览器中h5页面上拉下滑导致悬浮层脱离窗口的解决方法 (2) ...
- SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析
在SQL SERVER的查询语句中使用OR是否会导致不走索引查找(Index Seek)或索引失效(堆表走全表扫描 (Table Scan).聚集索引表走聚集索引扫描(Clustered Index ...
- bashrc文件中环境变量配置错误,导致linux命令无法正常使用的解决方案
分析原因 bashrc文件中环境变量配置错误,导致linux无法正常使用. 其实解决问题的方法很简单:把你在bashrc文件中写错的东西注释掉或者改写正确即可. 可是此时图形界面登陆不了,vim用不了 ...
- js 定时器(setTimeout/setInterval)出现变量未定义(xxx is not defined) 的解决方法
js 定时器(setTimeout/setInterval)出现变量未定义(xxx is not defined) 的解决方法 参考文章: (1)js 定时器(setTimeout/setInterv ...
- VMware vSphere Client中启动虚拟机提示No boot filename received/Operating System not found解决方法
VMware vSphere Client中启动虚拟机提示No boot filename received/Operating System not found解决方法 参考文章: (1)VMwar ...
- oracle中“ORA-00060: 等待资源时检测到死锁” 或存储过程编译卡死 解决方法
oracle中"ORA-00060: 等待资源时检测到死锁" 或存储过程编译卡死 解决方法 参考文章: (1)oracle中"ORA-00060: 等待资源时检测到死锁& ...
- Win7x64中使用VS调试WEB项目报“ORA-06413: 连接未打开”错误解决方法
错误描述 普通Web项目,Web项目在32位系统上跑的好好的,一点问题没有. 使用VS内置的开发服务器调试,页面能正常启动,但一连接数据库就报"ORA-06413: 连接未打开"错 ...
- 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 ...
- iOS中 H5的input输入框focus()无法自动拉起键盘(解决方法)
iOS中 H5的input输入框focus()无法自动拉起键盘(解决方法) 参考文章: (1)iOS中 H5的input输入框focus()无法自动拉起键盘(解决方法) (2)https://www. ...
最新文章
- 【Three.js】关于Three.js的辅助库ststs.js报错的解决方案
- mysql开启binlog启动慢_mysql配置开启binlog与慢查询日志功能
- ionic4监听返回事件 AppMinimize navController
- 《C++ Primer》7.5.2节练习
- web浏览器_Web上的分享(Share)API
- 接口测试工具--apipost脚本讲解
- MySQL索引(1)
- linux中安装pip镜像怎么设置_linux服务器怎么安装pip?
- 学习和研究下unity3d的四元数 Quaternion
- linux 输入--输出--重定向 stdin/stdout/stderr
- 计算机网络及电子邮件的原理,全国2006年4月全国自考计算机网络基本原理真题及答案..doc...
- 天网防火墙技术白皮书
- 如何将大硬盘对拷到小硬盘
- 基于spss的聚类分析(Cluster analysis)
- 计算机c盘无法扩展,C盘不够大怎么办 怎么扩展C盘容量合并硬盘分区
- IDEA打字冒火花教程
- jquery方法之append()与appendto()
- linux中mysql客户端命令行连接不了 docker 创建的mysql
- match2(双周赛)
- padding oracle attack相关之padding oracle attack