Oracle-oracle联合查询优化
现有下面一段sql如何能优化一下速度更快一点呢?
select * from A to_char(input_date,'yyyy-mm-dd') > '2012-06-15' and to_char(input_date,'yyyy-mm-dd') < '2012-07-01'and is_verify = '1'
and dj_id not in (select source_id from B where to_char(input_date,'yyyy-mm-dd') > '2012-06-15'
and to_char(input_date,'yyyy-mm-dd') < '2012-07-01' and source_id like '%DD%');
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
不知道你的业务是什么样子,但是尽量不要用not in,使用in进行索引查询,能快很多,在Oracle中not in是不通过索引的,但是in是通过索引检索数据,按照你的业务逻辑,修改一下使用in查询。
问题还是出在Not in 上面,像你说的这个些表是用于审核的话,这段SQL会直接导致系统崩溃,
正确的做法应该是分开执行两段SQL,将问题放入到应用中去处理
昨天看错了楼主的需求,把中间错误代码删掉了,以为楼主要查审核的数据,于是想了一下稍微麻烦点的方式来处理
--查询通过审核的数据
select * from A
where to_char(input_date, 'yyyy-mm-dd') > '2012-06-15'
and to_char(input_date, 'yyyy-mm-dd') < '2012-07-01'
and is_verify = '1'
and dj_id in (select source_id from B
where to_char(input_date,'yyyy-mm-dd') >'2012-06-15'
and to_char(input_date, 'yyyy-mm-dd') < '2012-07-01'
and source_id like '%DD%');)
--查询全部符合时间范围的数据
select * from A
where to_char(input_date, 'yyyy-mm-dd') > '2012-06-15'
and to_char(input_date, 'yyyy-mm-dd') < '2012-07-01'
and is_verify = '1'
最后在应用中从后者集合中移除出通过审核的数据,就得到了未通过审核的数据。
时间字段可以考虑函数索引,会快很多的。
另外,not in 还是用 not exists吧,这个用索引。
like的问题大家已经说了。
如果是PL SQL DEVELOPER,还是用F5看一下你的执行计划吧。
如果数据很多,把条件的日期格式化,数据库中储存的日期格式都是固定的
像现在这样格式化数据库中的数据,在数据量很大时,oracle会将每一条数据都格式化一遍,效率很低
个人觉得 not in 换成 not exists会好一些,另外like能不用就不要用
单看你上面的sql,不考虑你的业务逻辑,你的where条件里日期转换成数字形式应该比字符型要快很多,所以最好把日期通过to_number转换成数字类型:
select * from A
where to_number(to_char(input_date,'yyyymmdd')) > 20120615 and to_number(to_char(input_date,'yyyymmdd')) < 20120701 and is_verify = '1'
and dj_id not in (select source_id from B where to_number(to_char(input_date,'yyyymmdd')) > 20120615
and to_number(to_char(input_date,'yyyymmdd')) < 20120701 and source_id like '%DD%');
把not in 换成left join,另外注意索引问题
select A.* from A left join B on A.dj_id != B.dj_id where to_char(A.input_date,'yyyy-mm-dd') > '2012-06-15' and to_char(A.input_date,'yyyy-mm-dd') < '2012-07-01'and is_verify = '1'
and to_char(B.input_date,'yyyy-mm-dd') > '2012-06-15'
and to_char(B.input_date,'yyyy-mm-dd') < '2012-07-01' and B.source_id like '%DD%';
作左连接,如果A dj_id不等于B dj_id 就把A结果集查询出来
用外连接替代not in 减少使用模糊查询 影响效率