要将表的限制条件写到与该表同级别的where中
测试目的:将朱查询的限制条件放到子查询的where中,查看性能影响。
测试数据:
create table t1 as select object_id,object_name from dba_objects;
create table t2 as select object_id,object_name from user_objects;
create table t3 as select rownum object_id,table_name object_name from user_tables;
analyze table t1 compute statistics for table for all columns;
analyze table t2 compute statistics for table for all columns;
analyze table t3 compute statistics for table for all columns;
SQL> select count(*) from t1;
COUNT(*)
----------
26341
SQL> select count(*) from t2;
COUNT(*)
----------
13135
SQL> select count(*) from t3;
COUNT(*)
----------
5891
开始测试:
1.主查询条件出现在子查询的where中(确实有开发是这样写的SQL,或许是动态生成SQL或者因为不太了解SQL编写规范手动写的):
SQL> select *
2 from t1
3 where t1.object_id in
4 (select t2.object_id
5 from t2
6 where t1.object_name in (select t3.object_name from t3));
已选择5890行。
执行计划
----------------------------------------------------------
Plan hash value: 1276346997
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25583 | 2723K| | 244K (1)| 00:48:50 |
|* 1 | HASH JOIN SEMI | | 25583 | 2723K| 2280K| 244K (1)| 00:48:50 |
| 2 | TABLE ACCESS FULL | T1 | 25585 | 1973K| | 32 (0)| 00:00:01 |
| 3 | VIEW | VW_SQ_1 | 77M| 2213M| | 89634 (1)| 00:17:56 |
| 4 | NESTED LOOPS | | 77M| 2213M| | 89634 (1)| 00:17:56 |
| 5 | TABLE ACCESS FULL| T2 | 13135 | 166K| | 17 (0)| 00:00:01 |
| 6 | TABLE ACCESS FULL| T3 | 5891 | 97K| | 7 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"."OBJECT_ID"="T2.OBJECT_ID" AND "T1"."OBJECT_NAME"="ITEM_1")
Note
-----
- dynamic sampling used for this statement (level=4)
统计信息
----------------------------------------------------------
37 recursive calls
0 db block gets
316742 consistent gets
0 physical reads
0 redo size
184781 bytes sent via SQL*Net to client
4728 bytes received via SQL*Net from client
394 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
5890 rows processed
从执行计划可以看出,其实t2和t3走了笛卡尔积(SQL中这两个确实没有关联条件,从两个表nested loops后的返回基数77M可以看出,这两个表是走了笛卡尔积的)。笛卡尔积结果跟t1做hash join,t1将object_name传递给nested loop是的结果。返回5890条数据,消耗316742逻辑读。
这种性能方面的问题,我们是完全可以通过注意SQL的编码规范来规避的。
2.改写SQL,将主查询的限制条件放到与该其同级别的WHERE中。
SQL> select *
2 from t1
3 where t1.object_id in (select t2.object_id from t2)
4 and t1.object_name in (select object_name from t3);
已选择5890行。
执行计划
----------------------------------------------------------
Plan hash value: 3620957986
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 13135 | 1398K| 60 (4)| 00:00:01 |
|* 1 | HASH JOIN RIGHT SEMI | | 13135 | 1398K| 60 (4)| 00:00:01 |
| 2 | TABLE ACCESS FULL | T3 | 5891 | 97K| 9 (0)| 00:00:01 |
|* 3 | HASH JOIN RIGHT SEMI| | 13135 | 1180K| 50 (2)| 00:00:01 |
| 4 | TABLE ACCESS FULL | T2 | 13135 | 166K| 17 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | T1 | 25585 | 1973K| 32 (0)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"."OBJECT_NAME"="T3"."OBJECT_NAME")
3 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
Note
-----
- dynamic sampling used for this statement (level=4)
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
575 consistent gets
0 physical reads
0 redo size
184781 bytes sent via SQL*Net to client
4728 bytes received via SQL*Net from client
394 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
5890 rows processed
从执行计划来看,Oracle选择的表连接顺序都是最优的,逻辑读也从原来的316742下降到575,速度也提升很多。
切记:写SQL时一定要将对表的限制条件写到与该表同级别的where条件里。
要将表的限制条件写到与该表同级别的where中的更多相关文章
- 怎样加快master数据库的写操作?分表原则!将表水平划分!或者添加写数据库的集群
1.怎样加快master数据库的写操作?分表原则!将表水平划分!减少表的锁定时间!!! 或者或者添加写数据库的集群!!!或者添加写数据库的集群!!! 2.既然分表了,就一定要注意分表的规则!要在代码层 ...
- 用for; while...do; do...while; 写出九九乘法表
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- SQL纯手写创建数据库到表内内容
建表啥的只点点鼠标,太外行了,不如来看看我的纯手写,让表从无到有一系列:还有存储过程临时表,不间断的重排序: 一:建数据库 create Database Show on primary ( name ...
- 用Java写了一个程序,将一个Mysql库中的表,迁移到另外一个server上的Mysql库中
用Navicat做数据迁移,因为数据量比较大,迁移过过程中一个是进展不直观,另外就是cpu占用率高的时候,屏幕跟死机了一样点不动按钮,不好中断. 想了想,干脆自己写一个. 在网上找了一个sqllite ...
- 使用PowerShell读、写、删除注册表键值
访问注册表键值 在PowerShell中,用户可以通过类似于HKCU:(作为HKEY_CURRENT_USER)和HKLM:(代表HKEY_LOCAL_MATCHINE)的虚拟驱动器访问注册表键值. ...
- SQLServer将服务器A表写到服务器B表
不同服务器数据库之间的数据操作 --创建链接服务器 exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 ' ...
- 一个7重嵌套表EF添加语句,注意子表赋值过程中只需写子表主键赋值,不需要写子表外键=父表主键。EF创建时会自动将子表外键设为与父表主键相等
AIRPORT_HELIPORT tt = new AIRPORT_HELIPORT() { AIRPORT_HELIPORT_UUID = Gui ...
- mysql数据库 myisam数据存储引擎 表由于索引和数据导致的表损坏 的修复 和检查
一.mysqlcheck 进行表的检查和修复 1.检查mysqlisam存储引擎表的状态 #mysqlcheck -uuser -ppassword database table -c #检查单 ...
- [置顶] ※数据结构※→☆线性表结构(stack)☆============栈 序列表结构(stack sequence)(六)
栈(stack)在计算机科学中是限定仅在表尾进行插入或删除操作的线性表.栈是一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据.栈 ...
随机推荐
- hdu1715(Java)大数相加
大菲波数 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submissio ...
- 重载public Primes ():this(2,100)
当构造函数有多个重载的时候 想通过默认构造函数调用其他的重载的构造函数的话 就可以用:运算符public Primes():this(2, 100){//code }public Primes(int ...
- find which process occupy the PORT
mac : lsof -i:8080 linux : netstat -anltp | grep 8080
- 观察者模式Demo
using System; using System.Collections.Generic; namespace Demo { #region 抽象层,定义了观察者模式 /// &l ...
- IBM发布AppScan Source 8.7:减少iOS企业级应用安全风险
IBM发布AppScan Source 8.7:减少iOS企业级应用安全风险http://automationqa.com/forum.php?mod=viewthread&tid=2570& ...
- Android源码分析:HeaderViewListAdapter
http://bj007.blog.51cto.com/1701577/643568 对于手机开发,我一直坚持的是“用iPhone的方式开发iPhone应用,用Android的方式开发Android应 ...
- MVC小系列(二十)【给Action提供HttpStatusCodeResult】
主要用到: HttpStatusCodeResult 和HttpStatusCode 的http返回状态 比如: /// <summary> /// 使用异步模式 /// </sum ...
- 如何在VC++ 中调试MEX文件
MEX文件对应的是将C/C++文件语言的编写之后 得到的相关文件加载到Matlab中运行的一种方式, 现对于Matlab 中的某些程序运行效率而言, C/C++ 代码某些算法的领域上面执行效率很高,若 ...
- ipod nano 无法添加mp4视频 电影失败解决方法
我的是nano7. 导入mp4各种错误, 同步资料库 无效等等方法都没用. 后来发现当中 多个mp4,少年pi.mp4竟然导入成功, 怀疑是mp4格式不符合nano 于是:(测试后成功) 先拉到资料库 ...
- HDU 3555 Bomb (数位DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 题目大意:从0开始到给定的数字N所有的数字中遇到“49”的数字的个数. Sample Input ...