WHERE条件中or与union引起的全表扫描的问题
说起数据库的SQL语句执行效率的问题,就不得不提where条件语句中的or(逻辑或)引起的全表扫描问题,从而导致效率下降。
在以往绝大多数的资料中,大多数人的建议是使用 union 代替 or ,以解决由于使用了 OR 导致的全表扫描。然而,实际是不是如此呢?flymorn就拿5万多条数据的MSSQL数据库来测试。
在SQL Server查询分析器中键入如下代码:
SET STATISTICS io ON
SET STATISTICS time ON
go
select * from chuzu where c_id>1000 or c_qu='沙坪坝区' order by c_time desc
select * from chuzu where c_id>1000
union
select * from chuzu where c_qu='沙坪坝区' order by c_time desc
go
SET STATISTICS profile OFF
SET STATISTICS io OFF
SET STATISTICS time OFF
数据库设计中,id为主键,同时也是聚集索引,qu是普通字段列,两个条件中的字段是不一样的。
执行计划如下:
从执行计划中可以看出,采用了 union 的SQL语句的查询成本为50.22%,比采用 or 的成本 49.78%稍多,当然这只是计划。我们再来看看执行效率:
表 'chuzu'。扫描计数 1,逻辑读 2412 次,物理读 0 次,预读 0 次。
SQL Server 执行时间: CPU 时间 = 938 毫秒,耗费时间 = 3222 毫秒。
(所影响的行数为 52713 行)
表 'chuzu'。扫描计数 2,逻辑读 4774 次,物理读 0 次,预读 0 次。
SQL Server 执行时间: CPU 时间 = 1484 毫秒,耗费时间 = 4323 毫秒。
从这样的数据可以看出,采用了 union 的SQL语句的效率(4323 毫秒)实际上并没有比采用 or (3222 毫秒) 的高,耗费的时间也要多,采用了 or 的效率反而高出了25%。
如果where条件中的是同一个字段的话,执行效率也大体如上。
SET STATISTICS io ON
SET STATISTICS time ON
go
select * from chuzu where c_qu='九龙坡区' or c_qu='沙坪坝区' order by c_time desc
select * from chuzu where c_qu='九龙坡区'
union
select * from chuzu where c_qu='沙坪坝区' order by c_time desc
go
SET STATISTICS profile OFF
SET STATISTICS io OFF
SET STATISTICS time OFF
在这样的执行计划中,union 成本为 60.75% ,采用 or 的成本为 39.25%。依然是or的效率高。
再来看执行结果:
表 'chuzu'。扫描计数 1,逻辑读 2412 次,物理读 0 次,预读 0 次。
SQL Server 执行时间: CPU 时间 = 203 毫秒,耗费时间 = 635 毫秒。
(所影响的行数为 6131 行)
表 'chuzu'。扫描计数 2,逻辑读 4824 次,物理读 0 次,预读 0 次。
SQL Server 执行时间: CPU 时间 = 360 毫秒,耗费时间 = 798 毫秒。
采用union的执行时间 798 ms ,or的时间是 635ms,效率上来说,依然是 or 的效率高。
总结:我的测试结果正和网上说的相反,也许是因为我的数据量还不够大,才5万多的数据;或许当数据量到了百万千万级的时候,union 的效率 就会比 or 的高了。
所以,我的理解是在数据量还没有足够大,sql语句中还是尽量用 or 条件查询,因为数据量不大的情况下,即使全表扫描也要比逻辑读两次,扫描两次的时间要少,效率要高;当然,如果你的数据达到百万级别以上了,那就不要用 or 了,可以用 union 或 union all 代替 or ,以避免因为 or 引起的全表扫描。
WHERE条件中or与union引起的全表扫描的问题的更多相关文章
- SQL中哪些情况会引起全表扫描
1.模糊查询效率很低:原因:like本身效率就比较低,应该尽量避免查询条件使用like:对于like '%...%'(全模糊)这样的条件,是无法使用索引的,全表扫描自然效率很低:另外,由于匹配算法的关 ...
- SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析
在SQL SERVER的查询语句中使用OR是否会导致不走索引查找(Index Seek)或索引失效(堆表走全表扫描 (Table Scan).聚集索引表走聚集索引扫描(Clustered Index ...
- SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析 (转载)
在SQL SERVER的查询语句中使用OR是否会导致不走索引查找(Index Seek)或索引失效(堆表走全表扫描 (Table Scan).聚集索引表走聚集索引扫描(Clustered Index ...
- mysql in 中使用子查询,会不使用索引而走全表扫描
所以可以将 in 条件中 子查询转换成一张子表,从而通过 join 的形式进行条件限制.
- MySQL中的全表扫描和索引树扫描
引言 在学习mysql时,我们经常会使用explain来查看sql查询的索引等优化手段的使用情况.在使用explain时,我们可以观察到,explain的输出有一个很关键的列,它就是type属性,ty ...
- update的where条件要把索引的字段带上,要不然就全表锁
update的where条件要把索引的字段带上,要不然就全表锁 文章目录 update的where条件要把索引的字段带上,要不然就全表锁 本文主要内容 背景 ...
- oracle where 后面的条件中|| 是什么意思
oracle where 后面的条件中|| 是连接符号,Oracle中另一个concat函数能够连接两个字符串 concat(a,b) Oracle中nvl函数的使用方法和作用是什么? 假设你某个字段 ...
- Ext.Net 使用总结之查询条件中的起始日期
2.关于查询条件中起始日期的布局方式 首先上一张图,来展示一下我的查询条件的布局,如下: 大多数时候,我们的查询条件都是一个条件占一个格子,但也有不同的时候,如:查询条件是起始日期,则需要将这两个条件 ...
- TSQL:A表字段与B表中的关联,关联条件中一列是随机关联的实现方式
A表字段与B表中的关联,关联条件中一列是随机关联的实现方式 create table test( rsrp string, rsrq string, tkey string, distan strin ...
随机推荐
- VB6.0环境下的CATIA二次开发简介
CATIA作为CAD/CAE/CAM/PDM一体化的软件,广泛用于航空航天.汽车.船舶及电子工业,尤其在航空航天业,有八成以上厂商使用CATIA的市场[11].然而由于使用习惯和使用的侧重点不用,功能 ...
- solidity语言1
合约(contract)由变量(variable).函数(functions).函数修饰符(function modifiers).事件(events).结构体类型(struct type).枚举类型 ...
- day2 数据结构和一些基础知识
请查看我的云笔记链接: http://note.youdao.com/noteshare?id=4171342601326695ec87866e1cc3e410&sub=20CFB149543 ...
- RAC共享磁盘挂载工具
待更新: oracleasm: udev: 自己搭建个存储服务器:
- A full JDK must be specified
当你开发就了,你就发现,你遇到了各种奇葩的问题,结果,自己奇葩了. 背景:由于项目需要做安全恢复测试,然后,就搭一个新的库环境去测试: 配置jboss的运行jdk时,结果,蹦出个:A full JDK ...
- 第3次Scrum冲刺
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- mobile easyui兼容实体数据(tree插件为例)
ORM的实体类和数据库的类是一一对应的,如果有多级的嵌套循环json返回到前台为了方便展示可以使用mobile easyui,但是mobile easyui又需要特定的属性才可以,比如id,text, ...
- 牛客练习赛20(ABC)
A. 礼物 题意: 我从买奥利奥的事情中想出了一个算法题:假设某个店铺有N种不同类型的1元奥利奥和M种不同类型的2元奥利奥,而且余量无限,我的钱有k元,我想把k元都用来买奥利奥,且可以买同类型的奥利奥 ...
- 小草的Trouble学生信息管理系统
小草最近上课学C++,在图书馆纠结了好久,决定做这个小东西,没想到遇到了好多困难,好吧,功夫不负有心人,小草也在敲代码中提高了不少. 小草硬是学了好几天,才搞完这个东西,也算是了结了小草的一个心结. ...
- Manacher算法模板
题目描述 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 字符串长度为n 输入输出格式 输入格式: 一行小写英文字符a,b,c...y,z组成的字符串S 输出格 ...