说起数据库的SQL语句执行效率的问题,就不得不提where条件语句中的or(逻辑或)引起的全表扫描问题,从而导致效率下降。

在以往绝大多数的资料中,大多数人的建议是使用 union 代替 or ,以解决由于使用了 OR 导致的全表扫描。然而,实际是不是如此呢?flymorn就拿5万多条数据的MSSQL数据库来测试。

在SQL Server查询分析器中键入如下代码:

SET STATISTICS profile ON
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%稍多,当然这只是计划。我们再来看看执行效率:

(所影响的行数为 52713 行)
表 '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 profile ON
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的效率高。

再来看执行结果:

(所影响的行数为 6131 行)
表 '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引起的全表扫描的问题的更多相关文章

  1. SQL中哪些情况会引起全表扫描

    1.模糊查询效率很低:原因:like本身效率就比较低,应该尽量避免查询条件使用like:对于like '%...%'(全模糊)这样的条件,是无法使用索引的,全表扫描自然效率很低:另外,由于匹配算法的关 ...

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

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

  3. SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析 (转载)

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

  4. mysql in 中使用子查询,会不使用索引而走全表扫描

    所以可以将 in 条件中 子查询转换成一张子表,从而通过 join 的形式进行条件限制.

  5. MySQL中的全表扫描和索引树扫描

    引言 在学习mysql时,我们经常会使用explain来查看sql查询的索引等优化手段的使用情况.在使用explain时,我们可以观察到,explain的输出有一个很关键的列,它就是type属性,ty ...

  6. update的where条件要把索引的字段带上,要不然就全表锁

    update的where条件要把索引的字段带上,要不然就全表锁 文章目录 update的where条件要把索引的字段带上,要不然就全表锁        本文主要内容        背景        ...

  7. oracle where 后面的条件中|| 是什么意思

    oracle where 后面的条件中|| 是连接符号,Oracle中另一个concat函数能够连接两个字符串 concat(a,b) Oracle中nvl函数的使用方法和作用是什么? 假设你某个字段 ...

  8. Ext.Net 使用总结之查询条件中的起始日期

    2.关于查询条件中起始日期的布局方式 首先上一张图,来展示一下我的查询条件的布局,如下: 大多数时候,我们的查询条件都是一个条件占一个格子,但也有不同的时候,如:查询条件是起始日期,则需要将这两个条件 ...

  9. TSQL:A表字段与B表中的关联,关联条件中一列是随机关联的实现方式

    A表字段与B表中的关联,关联条件中一列是随机关联的实现方式 create table test( rsrp string, rsrq string, tkey string, distan strin ...

随机推荐

  1. 给Sublime text 3增加选中当前单词快捷键

    1.录制一份macro caret on a word –> ctrl+left –> ctrl+shift+right 2.将录制好的macro保存为select_current_wor ...

  2. March 27 2017 Week 13 Monday

    A book that remains shut is but a block. 有书闭卷不阅读,无异于一块木头. I had planned to buy a book and read it ev ...

  3. BZOJ3680:吊打XXX(模拟退火)

    Description gty又虐了一场比赛,被虐的蒟蒻们决定吊打gty.gty见大势不好机智的分出了n个分身,但还是被人多势众的蒟蒻抓住了.蒟蒻们将 n个gty吊在n根绳子上,每根绳子穿过天台的一个 ...

  4. Codeforces Round #512 (Div. 2, based on Technocup 2019 Elimination Round 1) C. Vasya and Golden Ticket 【。。。】

    任意门:http://codeforces.com/contest/1058/problem/C C. Vasya and Golden Ticket time limit per test 1 se ...

  5. node学习笔记(连载)

    这段时间玩了小程序.浏览器插件.koa建站,本来想写几篇文章总结一下的.迫于工作上有新需求要跟进,所以先写写读书笔记吧.公司九点上班,不过弹性工作时间,大家基本上九点半之前到.而我作为渣渣,八点半就到 ...

  6. 【luogu P2936 [USACO09JAN]全流Total Flow】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2936 菜 #include <queue> #include <cstdio> #i ...

  7. Android学习笔记_79_ Android 使用 搜索框

    1.在资源文件夹下创建xml文件夹,并创建一个searchable.xml: android:searchSuggestAuthorityshux属性的值跟实现SearchRecentSuggesti ...

  8. Android学习笔记_66_图片处理专题

    1.图片缩放:不解析整个图片信息. public class DemoActivity extends Activity { @Override public void onCreate(Bundle ...

  9. Android学习笔记_51_转android 加载大图片防止内存溢出

    首先来还原一下堆内存溢出的错误.首先在SD卡上放一张照片,分辨率为(3776 X 2520),大小为3.88MB,是我自己用相机拍的一张照片.应用的布局很简单,一个Button一个ImageView, ...

  10. HDU 1099 Lottery (求数学期望)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1099 Lottery Time Limit: 2000/1000 MS (Java/Others)   ...