编辑手记:前面我们介绍常用的子查询优化方法,但总有一些情况时在规律之外。谨慎处理方能不掉坑。

前文回顾:

作者简介:韩锋

精通包括Oracle、MySQL、informix等多种关系型数据库,有丰富的数据库架构设计开发经验。就职于宜信。

1、空值问题

首先值得关注的问题是,在NOT IN子查询中,如果子查询列有空值存在,则整个查询都不会有结果。这可能是跟主观逻辑上感觉不同,但数据库就是这样处理的。因此,在开发过程中,需要注意这一点。看个例子吧。SQL> select * from dual where 2 not in (select 1 from dual);

D

-

X

SQL> select * from dual where 2 not in (select 1 from dual union all select null from dual);

no rows selected

显然,第二条语句在印象中应该会返回记录,但实际情况就是没有。

第二个值得关注的是,在11g之前,如果主表和子表的对应列未同时有NOT NULL约束,或都未加IS NOT NULL限制,则Oracle会走FILTER。11g有新的ANTI NA(NULL AWARE)优化,可以正常对子查询进行UNNEST。

注意此时的关联字段OBJECT_ID,是可为空的。示例模拟了11g以前的情况,此时走了最原始的FILTER

在确定子查询列object_id不会有NULL存在的情况下,又不想通过增加NOT NULL约束来优化,可以通过上面方式进行改写

在11g的默认情况下,走的就是ANTI NA(NA=NULL AWARE)

2、OR问题

对含有OR的Anti Join或Semi Join,注意有FILTER的情况。如果FILTER影响效率,可以通过改写为UNION、UNION ALL、AND等逻辑条件进行优化。优化的关键要看FILTER满足条件的次数。看下面的示例。

//上例中包含有OR条件的Semi Join,执行计划中使用了FILTER过滤,整个逻辑读消耗为69。

//下面通过改写,看看效果如何?

//将上面的OR连接修改为UNION,消除了FILTER。从成本或逻辑读等角度来看,整个逻辑读为30,较前面的69大大降低了

3、[NOT] IN/EXISTS问题

下面看两个关于[NOT] IN/EXISTS的问题。

1. IN/EXISTS

从原理来讲,IN操作是先进行子查询操作,再进行主查询操作。EXISTS操作是先进行主查询操作,再到子查询中进行过滤。IN操作相当于对inner table执行一个带有distinct的子查询语句,然后得到的查询结果集再与outer table进行连接,当然连接的方式和索引的使用仍然等同于普通的两表连接。

EXISTS操作相当于对outer table进行全表扫描,用从中检索到的每一行与inner table做循环匹配输出相应的符合条件的结果,其主要开销是对outer table的全表扫描(full scan),而连接方式是nested loop方式。

当子查询表数据量巨大且索引情况不好(大量重复值等),则不宜使用产生对子查询的distinct检索而导致系统开支巨大的IN操作;反之当外部表数据量巨大(不受索引影响)而子查询表数据较少且索引良好时,不宜使用引起外部表全表扫描的EXISTS操作。如果限制性强的条件在子查询,一般建议使用IN操作。如果限制性强的条件在主查询,则使用EXISTS操作。

2. NOT IN/EXISTS

在子查询中,NOT IN子句将执行一个内部的排序和合并。无论在哪种情况下,NOT IN都是最低效的(因为它对子查询中的表执行了一个全表遍历)。

为了避免使用NOT IN,可以把它改写成外连接(Outer Joins)或NOT EXISTS。加入"云和恩墨大讲堂"微信群,参与讨论学习

oracle子查询不减少数据,Oracle性能优化-子查询到特殊问题相关推荐

  1. mysql百万数据根据索引查询_mysql创建多列索引查询百万表数据的性能优化经验分享...

    最近发现最代码网站中的收到的评论,提到我的,心情被赞的查询异常缓慢,通过nginx日志发现响应时间快的在5s,慢的有13s,终于忍无可忍花时间来解决了. 执行explain之后的截图如下: 可以看到p ...

  2. Oracle笔记(十二):性能优化篇

    目录 一.概述 二.修改系统全局区 三.修改进程全局区 四.优化查询 分析执行计划 使用索引 优化子查询 五.优化数据库结构 拆分表 增加中间 优化插入记录速度---禁用索引 禁用唯一性检查 使用批量 ...

  3. DELETE大批量数据的性能优化

    http://litterbaby.itpub.net/post/16841/276327 DELETE大批量数据的性能优化 问题的提出: 一个表有上千万的数据,欲从该表中删除部分数据: 在线用的生产 ...

  4. oracle取前5条数据,ORACLE查询前五条数据

    以下的文章主要介绍的是如何在Oracle实现 SELECT TOP N的实际操作方法,我们主要是以举例子的方式来引出Oracle实现 SELECT TOP N的具体操作,以下就文章的具体内容的描述,望 ...

  5. oracle 考试技巧,从 TPCH 测试学习性能优化技巧

    一.目标 TPCH是由TPC(Transaction Processing Performance Council)事务处理性能委员会公布的一套针对数据库决策支持能力的测试基准,通过模拟数据库中与业务 ...

  6. oracle 考试技巧,从 TPCH 测试学习性能优化技巧之 Q14

    一. 查询要求 Q14语句查询获得某一个月的收入中有多大的百分比是来自促销零件.用以监视促销带来的市场反应. Q14语句的特点是:带有聚集.连接操作的简单查询. 二. Oracle执行 Oracle编 ...

  7. oracle 取任意一条数据,oracle随机取一条数据详解

    Oracle 随机获取N条数据 当我们获取数据时,可能会有这样的需求,即每次从表中获取数据时,是随机获取一定的记录,而不是每次都获取一样的数据,这时我们可以采取Oracle内部一些函数,来达到这样的目 ...

  8. 大数据量性能优化之分页查询

    刷帖子翻页需要分页查询,搜索商品也需分页查询.当遇到上千万.上亿数据量,怎么快速拉取全量数据呢? 比如: 大商家拉取每月千万级别的订单数量到自己独立的ISV做财务统计 拥有百万千万粉丝的大v,给全部粉 ...

  9. oracle中插入日期型数据,ORACLE插入日期数据

    ORACLE插入日期数据 oracle数据库插入日期型数据 往Oracle数据库中插入日期型数据(to_date的用法) INSERT  INTO  FLOOR  VALUES  ( to_date ...

最新文章

  1. 敏捷为什么会失败之「PA-SA-WAKA-DA」理论
  2. python快速编程入门教程-终于懂得python快速编程入门教程
  3. 操作VR界面仅需眼神,Eyefluence眼控技术解放你的双手
  4. poj_2739 尺取法
  5. python多线程多进程多协程_python 多进程、多线程、协程
  6. DIY Virtual Wall for Roomba – Part One
  7. Java面向对象编程学习
  8. 在基于Spring的Web应用程序中使用Http Session
  9. 【codevs1316NOIP2012PJ】文化之旅,无题
  10. python的开发环境包括_下搭建 Python 开发环境
  11. 60-124-340-源码-运行模式-Yarn-通过 YARN 的资源本地化技术减少 Flink 在 YARN 上的部署时间
  12. Python实现TCP协议套接字多路复用
  13. BIM族库下载——10套知名地产Revit样板文件
  14. mac下载安装adb环境
  15. npm ERR! File exists: /XXX/xxx npm ERR! Move it away, and try again.
  16. 微信小程序------登录
  17. 哈雷拆分LiveWire上市,冲击美股电摩第一股
  18. 1060-勇者斗恶龙(BFS)
  19. c九宫重排_九宫重排 - mengfanrong - 博客园
  20. iphone怎么恢复备忘录

热门文章

  1. C++ 实验 5.12
  2. 常见一致性协议(一)
  3. struts2标签详解
  4. ios(iphone/ipad)一个简单的用代码判断当前设备的方法
  5. Oracle RMAN 设置和配置(一)
  6. 硅谷产品实战-总结:23、增长的核心在于减少用户阻力
  7. 纯 Git 实现前端 CI/CD
  8. 深入理解 ProtoBuf 原理与工程实践(概述)
  9. 高并发存储番外篇:Redis套路,一网打尽
  10. 漫画图解让美国颤抖的5G,到底牛在哪?