要将表的限制条件写到与该表同级别的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)在计算机科学中是限定仅在表尾进行插入或删除操作的线性表.栈是一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据.栈 ...
随机推荐
- solr 搜索引擎及搜索推荐应用
搜索框里输入关键字,从mongodb里搜索出关键字相关关键字记录.用户从相关关键字里选取一个作为最后关键字从solr里查询数据. 1创建索引:从sql里goodsinfo表查所有记录,solr.Add ...
- Nginx重要结构request_t解析之http请求的获取
请在文章页面明显位置给出原文连接,否则保留追究法律责任的权利. 本文主要参考为<深入理解nginx模块开发与架构解析>一书,处理用户请求部分,是一篇包含作者理解的读书笔记.欢迎指正,讨论. ...
- SpringMVC + ehcache( ehcache-spring-annotations)基于注解的服务器端数据缓存
背景 声明,如果你不关心java缓存解决方案的全貌,只是急着解决问题,请略过背景部分. 在互联网应用中,由于并发量比传统的企业级应用会高出很多,所以处理大并发的问题就显得尤为重要.在硬件资源一定的情况 ...
- G++ 教程(转)
简介 gcc and g++分别是GNU的c & c++编译器 gcc/g++在执行编译工作的时候,总共需要4步 1.预处理,生成.i的文件[预处理器cpp] 2.将预处理后的文 ...
- lscpu lsblk lsscsi lspci
[root@server1 ~]# lscpu Architecture: x86_64 CPU op-mode(s): -bit, -bit Byte Order: Little Endian CP ...
- Java基础知识强化之IO流笔记38:字符流缓冲流之BufferedWriter / BufferedReader使用
1. 字符流缓冲流: 字符流为了高效读写,也提供了对应的字符缓冲流. BufferedWriter:字符缓冲输出流 BufferedReader:字符缓冲输入流 2. BufferedWriter使用 ...
- 提升资源利用率的MapReduce框架
Hadoop系统提供了MapReduce计算框架的开源实现,像Yahoo!.Facebook.淘宝.中移动.百度.腾讯等公司都在借助 Hadoop进行海量数据处理.Hadoop系统性能不仅取决于任务调 ...
- 构建本地yum源之rpmbuild问题汇总
- check-rpaths的问题 今天在编译varnish的时候,遇到几个问题,其中一个就是出现如下错误: ...+ /usr/lib/rpm/check-rpaths /usr/lib/rpm/c ...
- Ganymed SSH-2 for Java
Ganymed SSH-2 for Java是一个纯Java实现的SHH2库,官网为http://www.ganymed.ethz.ch/ssh2/,最新的更新时间为2006年10月,在用之前,请仔细 ...
- POJ3974 Palindrome
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...