优化拥有谓词or的子查询
select distinct t.attr, t.item
from a t
where attr = :1
and (pro = :2 or exists
(select 1
from b hps
where hps.pro = :3
and t.pro = hps.sub_pro))
鉴于以往的经验,一开始就觉得子查询中的连接谓词or有问题。
注:
表a有50多万条记录,attr和pro上分别有索引;表b有10万条记录,pro上有单独索引,同时(pro,sub_pro)组成unique索引;
同时表a上的attr,pro字段的分布情况如下,对于表a,pro字段的选择性比attr高出了很多
SQL> select count(distinct pro),count(distinct attr) from a;
COUNT(DISTINCT pro) COUNT(DISTINCT attr)
------------------------- ---------------------------
164067 716
先通过set autotrace traceonly查看一把其执行计划和consistent gets
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 63 | 945 | 83 (2)| 00:00:01 |
| 1 | HASH UNIQUE | | 63 | 945 | 83 (2)| 00:00:01 |
|* 2 | FILTER | | | | | |
| 3 | TABLE ACCESS BY INDEX ROWID| a | 1268 | 19020 | 82 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | idx_a_attr | 1268 | | 8 (0)| 00:00:01 |
|* 5 | INDEX UNIQUE SCAN | idx_b_un_pro_sub | 1 | 12 | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("pro"=TO_NUMBER(:B) OR EXISTS (SELECT 0 FROM "b" "HPS" WHERE
"HPS"."SUB_pro"=:B1 AND "HPS"."pro"=TO_NUMBER(:C)))
4 - access("attr"=TO_NUMBER(:A))
5 - access("HPS"."pro"=TO_NUMBER(:C) AND "HPS"."SUB_pro"=:B1)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
4690 consistent gets
0 physical reads
0 redo size
589 bytes sent via SQL*Net to client
487 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
从执行计划看出,访问表a的时候选择了attr上的索引,实际效果不佳,逻辑读有4690;
通过等价改写后的sql如下,去除了谓词or,改用了union
select distinct t.attr, t.item
from a t
where attr = :a
and pro = :b
union
select distinct t.attr, t.item
from a t
where attr = :a
and exists
(select 1
from b hps
where hps.pro = :c
and t.pro = hps.sub_pro)
改写后的sql的执行计划如下
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6 | 150 | 16 (75)| 00:00:01 |
| 1 | SORT UNIQUE | | 6 | 150 | 16 (75)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
|* 3 | TABLE ACCESS BY INDEX ROWID| a | 1 | 15 | 4 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | idx_a_pro | 3 | | 3 (0)| 00:00:01 |
|* 5 | TABLE ACCESS BY INDEX ROWID| a | 1 | 15 | 3 (0)| 00:00:01 |
| 6 | NESTED LOOPS | | 5 | 135 | 10 (10)| 00:00:01 |
| 7 | SORT UNIQUE | | 5 | 60 | 2 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | idx_b_un_pro_sub | 5 | 60 | 2 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | idx_a_pro | 3 | | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("attr"=TO_NUMBER(:A))
4 - access("pro"=TO_NUMBER(:B))
5 - filter("attr"=TO_NUMBER(:A))
8 - access("HPS"."pro"=TO_NUMBER(:C))
9 - access("T"."pro"="HPS"."SUB_pro")
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
24 consistent gets
0 physical reads
0 redo size
589 bytes sent via SQL*Net to client
487 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
1 rows processed
访问表a时选择了pro上的索引,虽然增加了一次访问次数,但是逻辑读却下降到了24.
转载于:https://blog.51cto.com/xmffw/618156
优化拥有谓词or的子查询相关推荐
- SQL优化(三):子查询和IN,EXISTS用法和优化方法
用法 1. 与IN结合使用 子查询与IN结合使用时,通常通过子查询查询出某个表单列的值,然后作为外层的SELECT的IN查询的数据源,如下,查询今天进行了购物的用户列表,首先通过子查询在订单表t_or ...
- 标量子查询产生的SQL性能瓶颈,该怎么合理优化?
来自:DBAplus社群 作者介绍 郝昊喆,新炬网络数据库专家.擅长数据库方面的开发.整体架构及复杂SQL的调优,参与了多个行业核心系统的优化工作,目前专注于对开源技术.自动化运维和性能调优技术的研究 ...
- mysql semi join_MySQL 通过semi join 优化子查询
半连接是MySQL 5.6.5引入的,多在子查询exists中使用,对外部row source的每个键值,查找到内部row source匹配的第一个键值后就返回,如果找到就不用再查找内部row sou ...
- mysql in 原理_深入理解MySql子查询IN的执行和优化
IN为什么慢? 在应用程序中使用子查询后,SQL语句的查询性能变得非常糟糕.例如: SELECT driver_id FROM driver where driver_id in (SELECT dr ...
- SQL优化之一则MySQL中的DELETE、UPDATE 子查询的锁机制失效案例
关注"数据和云",精彩不容错过 前言 开发与维护人员避免不了与 in/exists.not in/not exists 子查询打交道,接触过的人可能知道 in/exists.not ...
- SQL Sever 子查询与嵌套查询
数据库表 1.带 in 的嵌套查询 查询Student表 并且 Sno 在 SC表中有 select * from Student where Sno in(select Sno from SC) 2 ...
- 浅谈 MySQL 子查询及其优化
2019独角兽企业重金招聘Python工程师标准>>> 使用过oracle或者其他关系数据库的DBA或者开发人员都有这样的经验,在子查询上都认为数据库已经做过优化,能够很好的选择驱动 ...
- oracle子查询不减少数据,Oracle性能优化-子查询到特殊问题
编辑手记:前面我们介绍常用的子查询优化方法,但总有一些情况时在规律之外.谨慎处理方能不掉坑. 前文回顾: 作者简介:韩锋 精通包括Oracle.MySQL.informix等多种关系型数据库,有丰富的 ...
- mysql子查询缺点_[慢查优化]慎用MySQL子查询,尤其是看到DEPENDENT SUBQUERY标记时
它的执行计划如下,请注意看关键词"DEPENDENT SUBQUERY": id select_type table type poss ...
最新文章
- 没做领导的时候,觉得领导都是傻X!做了领导之后觉得下属才是傻X!
- 轻量级数据库Sqlite的使用
- 面试官:Maven 的这 7 个问题你思考过没有?
- grpc ssl使用
- buck电路 dac stm32_STM32定时器学习---基本定时器
- 多进程event通信
- dede image.class.php,DEDE模板下载织梦DEDE 核心类TypeLink.class.php功能剖析
- Happy Mid-Autumn Festival !
- 重写 geturl Openlayers中使用TileCache加载预切割图片作为基础地图图层
- R语言报错:Error in scan
- 嵌入式Linux应用开发完全手册 pdf 韦东山
- LaTeX编写IEEE会议论文字体报错、且参考文献中会议/期刊的名字没有斜体的问题解决
- 电动按摩帖芯片FH8B23S16B单片机为什么这么多人用?
- java高级(java高级工程师证书)
- 动态仙人掌 系列题解之二——3465: 动态仙人掌 II
- C#为什么读作C Sharp
- 美国陪审团裁定福特向车祸遇难者家属赔偿17亿美元
- Tableau学习Step2一数据文件的读取与统计图、表的概述
- 【Argoverse 1 Motion Forecasting Dataset】轨迹预测数据集简介
- my ReadAnimal_hamster
热门文章
- 【深入浅出-JVM】(序)
- putty-psftp
- Docker Toolbox替换默认docker machine的存储位置
- 线程间通信共享变量和queue
- C#程序输出信息到调试窗口的几种方式
- Java集合类学习-LinkedList, ArrayList, Stack, Queue, Vector
- mysql数据库千万级别数据的查询优化和分页测试
- log4j用于读取.xml文件的出现了错误,类加载器.getResource(user.xml).getPath()返回路径空格变成了%20...
- PowerDesigner使用教程【转】
- 在MAC上搭建eclipse+android开发环境以及eclipse的svn插件的安装