sql语句,实践证明了某种情况下not in的效率高于not exists

只要百度not in和not exists,清一色的not exists的效率优于not in,毕竟not exists只是去强调是否返回结果集,只是一个bool值,而not in是返回一个结果集,是由大量大量数据构成的。所以一开始我在做的时候写的是not in,然后前辈告诉我效率太低,改成了not exists,结果查询速度特别慢。为什么呢?首先来看看sql语句,本身sql语句特别长,只写出where条件中的not in和not exists筛选部分语句。

not in: where substr(表A.字段A,1,9) not in (select substr(字段B,1,9) from 表B) and 表A.字段C not in (select 字段D from 表C)

not exists:where not exists (select 1 from 表B where substr(表B.字段B,1,9) = substr(表A.字段A,1,9) and not exists (select 1 from 表C where 表C.字段D = 表A.字段C)

主表是表A,大概也就不超过10万的数据量吧,然后前面表A先做过一次inner join和两次left join,inner join排除了表A中将近六分之五的数据,两次left join中一次是替换掉表A中的某个字段的值,另一次多取一次值。这些处理都花极其少的时间。然后现在这么做远远不够,表A还要根据另外两张表中的数据来进行再次过滤。这个行为就是通过两个not in来完成的。一开始借鉴了前辈的提议,用了not exists,毕竟返回一个bool值是大量的节省时间,然后实际结果下来却花了整整3秒多,这对于一个用户来是完完全全不能接受的。为什么原因呢?最后推导出原因肯定是在前一句not exists中的两个substr。表B中大概只有5000不到的数据,然而表A里面却有几万条数据,用表B中的每个值和表A中的每个值都要进行一次比较处理,那会是多么一个庞大的处理!!尽管not exists只是返回一个bool值,但是却忽略了里面select语句中where的处理量,而且还要进行一次substr处理。一开始没有想到再去用not in处理,先想到的用的是视图,因为想去除掉一次substr处理,提前把表A中的数据处理好放到视图里,然后再进行处理。结果更加令人意外,视图更加慢,而且还取不到正确结果。这部分的原因我猜应该是表A里面有两个主键,而我做视图的过程中只取了其中一个主键,但是这个取出的这个主键是受后面那个主键约束的,创建了垃圾数据比较多的视图。(其实我本来也不太会视图,还是前辈教的= =。。)我抱着破罐子破摔的想法把not exists换成了not in,然后奇迹出现了,取完整个数据0.1秒一下级别的,反正一眨眼的时间。。完美的符合了系统不管什么处理都不能超过3秒的要求。。

为什么not in在这种情况下效率远远高于not exists呢?按我一介菜鸟的理解,not exists里面的where处理拖慢了整个速度,况且这次处理本来就是想要返回结果集,况且在这之前已经拿了表A.字段A,最终正确的数据是根据这个字段A来获取的,只要拿出不与从其它两张表不匹配的数据即可,就相当于整理衣柜,把没用的衣服拿出来这一个过程而已。而且字段A,B,C,D都是各个表的主键,不存在null值这种概念,没有必要进行额外的判断。所以最后not in的速度比not exists整整快了3秒有余。

数据库是DB2(不要吐槽,日企就是这么喜欢IBM,顶层终于考虑要换oracle。。。)

一介菜鸟,写的错误的地方,欢迎大神提意见,谢谢~~

时间: 2024-10-13 18:17:09

sql语句,实践证明了某种情况下not in的效率高于not exists的相关文章

百度分页在某种情况下突然变了

百度分页在某种情况下突然变了 挺奇怪的,我是先搜索某个关键字,然后点视频,然后再点回来网页,就出现了这个新分页页面,奇怪吧,嘿嘿 你们有没有碰到过?

SQL&EF优化第一篇 各种情况下的性能测试之count函数篇

测试环境  mssql 08  +win7    数据 30W条 二〇一六年十月二十九日 09:04:43 结论: *>1>主键>可空列    推测未论证: 根据情况优先选择* 因*无需判断某一列是否存在数据  1则是每次仍需要判断

优化sql,返回行数少情况下,NL比hash快好多

sql如下 select t.id, t.value, tt.sort as sortno from ENGINEERING_TYPE t left join ENGINEERING_TYPE tt on t.parentid = tt.id where t.delete_flag = 0 and t.hasson = 0 order by sortno, t.sort sql很简单,相当于自连接 ,返回行数12行,非常小,但是运行5s左右才出结果 看一下执行计划 可以看到,表与表之间走了has

SQL语句实践

1 use around; 2 3 CREATE TABLE class ( cid TINYINT PRIMARY KEY auto_increment, caption VARCHAR ( 20 ) ); 4 CREATE TABLE student ( 5 sid TINYINT PRIMARY KEY auto_increment, 6 sname VARCHAR ( 20 ), 7 gender VARCHAR ( 10 ), 8 class_id TINYINT, 9 CONSTRA

优化SQL查询:如何写出高性能SQL语句

1.首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句,如果用来从一个10万条记录的表中查1条记录,那查询优化器会选择“索引查找”方式,如果该表进行了归档,当前只剩下5000条记录了,那查询优化器就会改变方案,采用“全表扫描”方式. 可见,执行计划并不是固定的,它是“个性化的“.产生一个正确的”执行计划“有两点很重要: (1)SQL语句是否清晰地告诉查询优化器它想干什么? (2)查询优化器得到

mysql下sql语句 update 字段=字段+字符串

原文:mysql下sql语句 update 字段=字段+字符串 mysql下sql语句令某字段值等于原值加上一个字符串 update 表明 SET 字段= 'feifei' || 字段; (postgreSQL 用 || 来连贯字符串) MySQL连贯字符串不能利用加号(+),而利用concat. 比方在aa表的name字段前加字符'x',利用: update aa set name=concat('x',name) 原文地址:https://www.cnblogs.com/lonelyxmas

SQL语句技巧(上个样式太差了)

以下并非本人整理,但是看后感觉相当不错,特此分享. 1.应用程序中,保证在实现功能的基础上,尽量减少对数据库的访问次数:通过搜索参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担:能够分开的操作尽量分开处理,提高每次的响应速度:在数据窗口使用SQL时,尽量把使用的索引放在选择的首列:算法的结构尽量简单:在查询时,不要过多地使用通配符如SELECT * FROM T1语句,要用到几列就选择几列如:SELECT COL1,COL2 FROMT1:在可能的情况下尽量限制尽量结果集行数如:SE

ORACLE中能否找到未提交事务的SQL语句

  在Oracle数据库中,我们能否找到未提交事务(uncommit transactin)的SQL语句或其他相关信息呢?  关于这个问题,我们先来看看实验测试吧.实践出真知. 首先,我们在会话1(SID=63)中构造一个未提交的事务,如下所: SQL> create table test   2  as   3  select * from dba_objects;   Table created. SQL> select userenv('sid') from dual;   USEREN

sql语句的优化分析

摘自  http://www.cnblogs.com/knowledgesea/p/3686105.html sql语句性能达不到你的要求,执行效率让你忍无可忍,一般会时下面几种情况. 网速不给力,不稳定. 服务器内存不够,或者SQL 被分配的内存不够. sql语句设计不合理 没有相应的索引,索引不合理 没有有效的索引视图 表数据过大没有有效的分区设计 数据库设计太2,存在大量的数据冗余 索引列上缺少相应的统计信息,或者统计信息过期 .... 那么我们如何给找出来导致性能慢的的原因呢? 首先你要