一哥们问我,怎么才能让子查询作为驱动表? SQL如下:

select  rowid rid
from its_car_pass7 v
where 1 = 1
and pass_datetime >=
to_date('2013-07-06 :17:46:04', 'yyyy-mm-dd hh24:mi:ss')
and pass_datetime <=
to_date('2013-07-06 :18:46:06', 'yyyy-mm-dd hh24:mi:ss')
and v.pass_device_unid in
(select unid
from its_base_device
where dev_bay_unid in ('01685EFE4658C19D59C4DDAAEDD37393')
and dev_type = '1'
and dev_chk_flag = '1'
and dev_delete_flag = 'N')
order by v.pass_datetime asc
/

执行计划如下:

Execution Plan
----------------------------------------------------------
Plan hash value: 3634433140 --------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 111 | 2 (50)| 00:00:01 | | |
| 1 | SORT ORDER BY | | 1 | 111 | 2 (50)| 00:00:01 | | |
| 2 | NESTED LOOPS | | | | | | | |
| 3 | NESTED LOOPS | | 1 | 111 | 1 (0)| 00:00:01 | | |
| 4 | PARTITION RANGE SINGLE | | 1 | 39 | 1 (0)| 00:00:01 | 1284 | 1284 |
|* 5 | INDEX SKIP SCAN | IDX_VT7_DEVICEID | 1 | 39 | 1 (0)| 00:00:01 | 1284 | 1284 |
|* 6 | INDEX UNIQUE SCAN | PK_ITS_BASE_DEVICE | 1 | | 0 (0)| 00:00:01 | | |
|* 7 | TABLE ACCESS BY INDEX ROWID| ITS_BASE_DEVICE | 1 | 72 | 0 (0)| 00:00:01 | | |
-------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 5 - access("PASS_DATETIME">=TO_DATE(' 2013-07-06 17:46:04', 'syyyy-mm-dd hh24:mi:ss') AND
"PASS_DATETIME"<=TO_DATE(' 2013-07-06 18:46:06', 'syyyy-mm-dd hh24:mi:ss'))
filter("PASS_DATETIME">=TO_DATE(' 2013-07-06 17:46:04', 'syyyy-mm-dd hh24:mi:ss') AND
"PASS_DATETIME"<=TO_DATE(' 2013-07-06 18:46:06', 'syyyy-mm-dd hh24:mi:ss'))
6 - access("V"."PASS_DEVICE_UNID"="UNID")
7 - filter("DEV_BAY_UNID"='01685EFE4658C19D59C4DDAAEDD37393' AND "DEV_TYPE"='1' AND
"DEV_DELETE_FLAG"='N' AND "DEV_CHK_FLAG"='1') Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
110973 consistent gets
0 physical reads
0 redo size
47861 bytes sent via SQL*Net to client
1656 bytes received via SQL*Net from client
105 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
1560 rows processed

这里我们就不管统计信息是否准确了,也不管SQL优化的问题,就单单讨论哥们问的问题吧。

那哥们说,怎么才能让子查询作为驱动表呢?他自己试了很多方法就是搞不定。 那我们来亲自搞搞吧

explain plan for   select  rowid rid
from its_car_pass7 v
where 1 = 1
and pass_datetime >=
to_date('2013-07-06 :17:46:04', 'yyyy-mm-dd hh24:mi:ss')
and pass_datetime <=
to_date('2013-07-06 :18:46:06', 'yyyy-mm-dd hh24:mi:ss')
and v.pass_device_unid in
(select unid
from its_base_device
where dev_bay_unid in ('01685EFE4658C19D59C4DDAAEDD37393')
and dev_type = '1'
and dev_chk_flag = '1'
and dev_delete_flag = 'N')
order by v.pass_datetime asc
/

执行计划如下

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, NULL, 'ADVANCED -PROJECTION'));

-----------------------------------------------------------
Plan hash value: 2191740724
---------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
---------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 111 | 2092K (1)| 06:58:26 | | |
| 1 | NESTED LOOPS | | | | | | | |
| 2 | NESTED LOOPS | | 1 | 111 | 2092K (1)| 06:58:26 | | |
| 3 | PARTITION RANGE SINGLE | | 1 | 39 | 2092K (1)| 06:58:26 | 1284 | 1284 |
| 4 | TABLE ACCESS BY LOCAL INDEX ROWID| ITS_CAR_PASS7 | 1 | 39 | 2092K (1)| 06:58:26 | 1284 | 1284 |
|* 5 | INDEX RANGE SCAN | IDX_VT7_DATETIME | 1 | | 6029 (1)| 00:01:13 | 1284 | 1284 |
|* 6 | INDEX UNIQUE SCAN | PK_ITS_BASE_DEVICE | 1 | | 0 (0)| 00:00:01 | | |
|* 7 | TABLE ACCESS BY INDEX ROWID | ITS_BASE_DEVICE | 1 | 72 | 0 (0)| 00:00:01 | | |
--------------------------------------------------------------------------------------------------------------------------- Query Block Name / Object Alias (identified by operation id):
------------------------------------------------------------- 1 - SEL$5DA710D3
4 - SEL$5DA710D3 / V@SEL$1
5 - SEL$5DA710D3 / V@SEL$1
6 - SEL$5DA710D3 / ITS_BASE_DEVICE@SEL$2
7 - SEL$5DA710D3 / ITS_BASE_DEVICE@SEL$2 Outline Data
------------- /*+
BEGIN_OUTLINE_DATA
NLJ_BATCHING(@"SEL$5DA710D3" "ITS_BASE_DEVICE"@"SEL$2")
USE_NL(@"SEL$5DA710D3" "ITS_BASE_DEVICE"@"SEL$2")
LEADING(@"SEL$5DA710D3" "V"@"SEL$1" "ITS_BASE_DEVICE"@"SEL$2")
INDEX(@"SEL$5DA710D3" "ITS_BASE_DEVICE"@"SEL$2" ("ITS_BASE_DEVICE"."UNID"))
INDEX_RS_ASC(@"SEL$5DA710D3" "V"@"SEL$1" ("ITS_CAR_PASS7"."PASS_DATETIME"))
OUTLINE(@"SEL$2")
OUTLINE(@"SEL$1")
UNNEST(@"SEL$2")
OUTLINE_LEAF(@"SEL$5DA710D3")
FIRST_ROWS
DB_VERSION('11.2.0.3')
OPTIMIZER_FEATURES_ENABLE('11.2.0.3')
IGNORE_OPTIM_EMBEDDED_HINTS
END_OUTLINE_DATA
*/ Predicate Information (identified by operation id):
--------------------------------------------------- 5 - access("PASS_DATETIME">=TO_DATE(' 2013-07-06 17:46:04', 'syyyy-mm-dd hh24:mi:ss') AND
"PASS_DATETIME"<=TO_DATE(' 2013-07-06 18:46:06', 'syyyy-mm-dd hh24:mi:ss'))
6 - access("V"."PASS_DEVICE_UNID"="UNID")
7 - filter("DEV_BAY_UNID"='01685EFE4658C19D59C4DDAAEDD37393' AND "DEV_TYPE"='1' AND "DEV_DELETE_FLAG"='N' AND
"DEV_CHK_FLAG"='1')

TMD 执行计划又变了,我们也先别管执行计划为啥变了,驱动表仍然是 ITS_CAR_PASS7,现在我们来改变驱动表

select /*+ leading(ITS_BASE_DEVICE@SEL$2) */ rowid rid
from its_car_pass7 v
where 1 = 1
and pass_datetime >=
to_date('2013-07-06 :17:46:04', 'yyyy-mm-dd hh24:mi:ss')
and pass_datetime <=
to_date('2013-07-06 :18:46:06', 'yyyy-mm-dd hh24:mi:ss')
and v.pass_device_unid in
(select unid
from its_base_device
where dev_bay_unid in ('01685EFE4658C19D59C4DDAAEDD37393')
and dev_type = '1'
and dev_chk_flag = '1'
and dev_delete_flag = 'N')
order by v.pass_datetime asc
/ Execution Plan
----------------------------------------------------------
Plan hash value: 712001411 -------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 111 | 25 (4)| 00:00:01 | | |
| 1 | SORT ORDER BY | | 1 | 111 | 25 (4)| 00:00:01 | | |
|* 2 | TABLE ACCESS BY LOCAL INDEX ROWID| ITS_CAR_PASS7 | 1 | 39 | 2 (0)| 00:00:01 | 1284 | 1284 |
| 3 | NESTED LOOPS | | 1 | 111 | 24 (0)| 00:00:01 | | |
|* 4 | TABLE ACCESS BY INDEX ROWID | ITS_BASE_DEVICE | 6 | 432 | 12 (0)| 00:00:01 | | |
|* 5 | INDEX RANGE SCAN | IDX_DEVICE_DEV_BAY_UNID | 7 | | 1 (0)| 00:00:01 | | |
| 6 | PARTITION RANGE SINGLE | | 44M| | 2 (0)| 00:00:01 | 1284 | 1284 |
|* 7 | INDEX RANGE SCAN | IDX_VT7_PASS_DEVICE_UNID | 44M| | 2 (0)| 00:00:01 | 1284 | 1284 |
------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - filter("PASS_DATETIME">=TO_DATE(' 2013-07-06 17:46:04', 'syyyy-mm-dd hh24:mi:ss') AND
"PASS_DATETIME"<=TO_DATE(' 2013-07-06 18:46:06', 'syyyy-mm-dd hh24:mi:ss'))
4 - filter("DEV_TYPE"='1' AND "DEV_DELETE_FLAG"='N' AND "DEV_CHK_FLAG"='1')
5 - access("DEV_BAY_UNID"='01685EFE4658C19D59C4DDAAEDD37393')
7 - access("V"."PASS_DEVICE_UNID"="UNID") Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
18645 consistent gets
130 physical reads
0 redo size
47861 bytes sent via SQL*Net to client
1657 bytes received via SQL*Net from client
105 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
1560 rows processed

驱动表改了之后,逻辑读从11W降低为1.8W

如何让in/exists 子查询(半连接)作为驱动表?的更多相关文章

  1. mysql---where子查询、form子查询、exists子查询

    1.什么是子查询? 当一个查询是另一个查询的条件时,称之为子查询. 2.子查询有什么好处? 子查询可以使用几个简单命令构造功能强大的复合命令. 那么,现在让我们一起来学习子查询. 3.where型的子 ...

  2. 关于T-SQL中exists或者not exists子查询的“伪优化”的做法

    问题起源 在使用t-sql中的exists(或者not exists)子查询的时候,不知道什么时候开始,发现一小部分人存在一种“伪优化”的一些做法,并且向不明真相的群众传递这一种写法“优越性”,实在看 ...

  3. 7-14 EXISTS子查询

    EXISTS: 只注重于子查询是否有返回行,如果查有返回行返回结果为值,否则为假 并不使用子查询的结果,仅用于测试子查询是否有返回结果. 语法: IF EXISTS (子查询) BEGIN 语句块 E ...

  4. JOIN与EXISTS(子查询)的效率研究

    使用MySQL提供的Sample数据库Sakila 现将profiling打开,用来一会查看sql执行时间 set profiling=1; exists 子查询与 join联接效率的对比,功能:查看 ...

  5. in型子查询陷阱,exists子查询

    in 型子查询引出的陷阱 select goods_id from goods where cat_id in (1,2,3) 直接用id,不包含子查询,不会中陷阱 题: 在ecshop商城表中,查询 ...

  6. mysql优化---in型子查询,exists子查询,from 型子查询

    in型子查询引出的陷阱:(扫更少的行,不要临时表,不要文件排序就快) 题: 在ecshop商城表中,查询6号栏目的商品, (注,6号是一个大栏目) 最直观的: mysql); 误区: 给我们的感觉是, ...

  7. Mysql常用sql语句(19)- in / exists 子查询

    测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 前言 子查询在我们查询方法中是比较常用的,通过子查询可 ...

  8. [慢查优化]联表查询注意谁是驱动表 & 你搞不清楚谁join谁更好时请放手让mysql自行判定

    写在前面的话: 不要求每个人一定理解 联表查询(join/left join/inner join等)时的mysql运算过程: 不要求每个人一定知道线上(现在或未来)哪张表数据量大,哪张表数据量小: ...

  9. 【转】[慢查优化]联表查询注意谁是驱动表 & 你搞不清楚谁join谁更好时请放手让mysql自行判定

    转自:http://zhengyun-ustc.iteye.com/blog/1942797 写在前面的话: 不要求每个人一定理解 联表查询(join/left join/inner join等)时的 ...

随机推荐

  1. golang之数据结构

    4种:bool/int/uint/uintptr(其中bool类型的零值为false,其余类型的零值为0) 4种:float32/float64/complex64/complex126 (零值为0) ...

  2. 写一个杀死Gradle Daemon的shell脚本和bat脚本

    1. Gradle Daemon也就是Gradle守护进程 Gradle需要运行在一个Java虚拟机中,每一次执行gradle命令就意味着一个新的Java虚拟机被启动,然后加载Gradle类和库,最后 ...

  3. Linux常用命令3 文件搜索命令

    文件搜索非常占用资源,所以尽量不要使用这个命令 避免少用该命令最好的方式是设置好文件夹结构,文件不要乱放 1.文件搜索命令:find 命令名称:find 所在路径:/bin/find 执行权限:所有用 ...

  4. JVM学习篇章(二)

     上节我们已经介绍了jvm和监控的一下方法,下面举例说明一下:  瓶颈问题定位: 内存泄漏原因定位: 1.常见的内存泄漏 2.定位的方法

  5. 使用JS如何消除一个数组里重复的元素

    JS: var arrData = [1,3,5,7,7,8,9,3,10,8,"sdsdsds","sss","ffff","s ...

  6. 获取文章,显示时自动换行(word-break与 work-wrap的区别)

    HTML:<div class="na-i"> <span> </span></div>样式:.na-i{ overflow-y: ...

  7. 模板内置函数(HTML)

    模板内置函数 注意:1.html书写避免多余的空格,否则可能无法被识别 2.模板是用来渲染的不要用来处理逻辑 后台ctime=datetime.datatime.now() {{ctime|date: ...

  8. bzoj1179 Atm

    Description Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口 ...

  9. Notepad++中Python脚本运行出现语法错误:IndentationError: unindent does not match any outer indentation level

    使用Notepad++编辑python代码运行遇到了这个问题: IndentationError: unindent does not match any outer indentation leve ...

  10. maven 从svn导入项目遇到的问题 No marketplace entries found to handle yuicompressor maven plugin:1.3.0:compile

    版权声明:本文为博主原创文章,未经博主同意不得转载.安金龙 的博客. https://blog.csdn.net/smile0198/article/details/25463825 RT.使用ecl ...