【书评:Oracle查询优化改写】第三章
2015-05-18 15:14
330 查看
【书评:Oracle查询优化改写】第三章 BLOG文档结构图
一.1 导读
各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① 隐含参数 _b_tree_bitmap_plans介绍 ② 11g新特性Native Full Outer Join 本文如有错误或不完善的地方请大家多多指正,ITPUB留言或QQ皆可,您的批评指正是我写作的最大动力。一.2 实验环境介绍
oracle:11.2.0.3 、8.1.7.0.0 OS: RHEL6.5一.3 前言
前2章的链接参考相关连接: 【书评:Oracle查询优化改写】第一章 http://blog.itpub.net/26736162/viewspace-1652985/ 【书评:Oracle查询优化改写】第二章 http://blog.itpub.net/26736162/viewspace-1654252/ 昨天晚上(5.14)看完了《Oracle查询优化改写》的第三章,不得不说下这本书里边代码的排版有很大问题,格式老是不对齐,尤其是执行计划的格式,可能是印刷的时候出现的问题吧,不说这个了。这个第三章主要是讲多表的关联,包括各种连接的写法,如左联、右联,以及过滤条件错误地放在WHERE里会有什么影响;当数据有重复值时要直接关联还是分组汇总后再关联。 第 3 章 操作多个表 3.1 UNION ALL 与空字符串 3.2 UNION 与 OR 3.3 组合相关的行 3.4 IN、EXISTS 和 INNER JOIN 3.5 INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL JOIN 解析 3.6 自关联 3.7 NOT IN、NOT EXISTS 和 LEFT JOIN 3.8 外连接中的条件不要乱放 3.9 检测两个表中的数据及对应数据的条数是否相同 3.10 聚集与内连接 3.11 聚集与外连接 3.12 从多个表中返回丢失的数据 3.13 多表查询时的空值处理 下边我就针对一些重点,或者说是我自己也不是很懂的部分做做研究吧。一.4 隐含参数 _b_tree_bitmap_plans 实验
一.4.1 简介
该参数为隐含参数,是指是否将索引转换为oracle9i之前默认值为true。可以这样认为,如有两个字段B都有oracle有可能将这两个索引转换成and操作得出结果集。如果改为btree的索引,我们可以将该参数在false,也可以加Oracle也可以将数据记录的_b_tree_bitmap_plans设置为”(“或BITMAP OR来判断位图所映射的一批数据记录是否满足条件。 eygle大师的一个例子: http://www.eygle.com/archives/2011/12/bitmap_conversion_cpu.html一.4.2 11g情况下
[root@rhel6_lhr ~]# su - oracle [oracle@rhel6_lhr ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.3.0 Production on Fri May 10:16:10 2015 Copyright (c) 1982, 2011, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, Automatic Storage Management, OLAP, Data Mining and Real Application Testing options 10:16:10 SQL> 10:16:10 SQL> conn lhr/lhr Connected. 10:16:10 SQL> create table emp_bk as select * from scott.emp; Table created. Elapsed: 00:00:03.43 10:16:15 SQL> create index idx_emp_empno on emp_bk(empno); Index created. Elapsed: 00:00:00.05 10:19:26 SQL> create index idx_emp_ename on emp_bk(ename); Index created. Elapsed: 00:00:00.04 10:20:48 SQL> explain plan for select empno,ename from emp_bk where empno=7788 or ename='SCOTT'; Explained. Elapsed: 00:00:00.09 10:20:56 SQL> select * from table(dbms_xplan.display); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Plan hash value: 4193090541 -------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 20 | 2 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID | EMP_BK | 1 | 20 | 2 (0)| 00:00:01 | | 2 | BITMAP CONVERSION TO ROWIDS | | | | | | | 3 | BITMAP OR | | | | | | | 4 | BITMAP CONVERSION FROM ROWIDS| | | | | | |* 5 | INDEX RANGE SCAN | IDX_EMP_EMPNO | | | 1 (0)| 00:00:01 | | 6 | BITMAP CONVERSION FROM ROWIDS| | | | | | |* 7 | INDEX RANGE SCAN | IDX_EMP_ENAME | | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 5 - access("EMPNO"=7788) 7 - access("ENAME"='SCOTT') Note ----- - dynamic sampling used for this statement (level=2) 24 rows selected. Elapsed: 00:00:00.52 10:24:06 SQL> conn / as sysdba Connected. Elapsed: 00:00:00.03 10:24:34 SQL> set pagesize 9999 10:24:41 SQL> set line 9999 10:24:41 SQL> col NAME format a30 10:24:41 SQL> col KSPPDESC format a50 10:24:41 SQL> col KSPPSTVL format a20 10:24:42 SQL> SELECT a.INDX, 10:24:42 2 a.KSPPINM NAME, 10:24:42 3 a.KSPPDESC, 10:24:42 4 b.KSPPSTVL 10:24:42 5 FROM x$ksppi a, 10:24:42 6 x$ksppcv b 10:24:42 7 WHERE a.INDX = b.INDX 10:24:42 8 and lower(a.KSPPINM) like lower('%¶meter%'); Enter value for parameter: _b_tree_bitmap_plans old 8: and lower(a.KSPPINM) like lower('%¶meter%') new 8: and lower(a.KSPPINM) like lower('%_b_tree_bitmap_plans%') INDX NAME KSPPDESC KSPPSTVL ---------- ------------------------------ -------------------------------------------------- -------------------- 1910 _b_tree_bitmap_plans enable the use of bitmap plans for tables w. only TRUE B-tree indexes Elapsed: 00:00:00.01 10:25:44 SQL> conn lhr/lhr Connected. 10:26:56 SQL> alter session set "_b_tree_bitmap_plans" = false; Session altered. Elapsed: 00:00:00.00 10:27:01 SQL> show parameter _b_tree_bitmap_plans NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ _b_tree_bitmap_plans boolean FALSE 10:27:05 SQL> explain plan for select empno,ename from emp_bk where empno=7788 or ename='SCOTT'; Explained. Elapsed: 00:00:00.01 10:27:14 SQL> select * from table(dbms_xplan.display); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Plan hash value: 370270337 ---------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 20 | 3 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| EMP_BK | 1 | 20 | 3 (0)| 00:00:01 | ---------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("EMPNO"=7788 OR "ENAME"='SCOTT') Note ----- - dynamic sampling used for this statement (level=2) 17 rows selected. Elapsed: 00:00:00.04 10:27:18 SQL> explain plan for select empno,ename from emp_bk where empno=7788 10:27:49 2 union 10:27:55 3 select empno,ename from emp_bk where ename='SCOTT'; Explained. Elapsed: 00:00:00.00 10:28:07 SQL> select * from table(dbms_xplan.display); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Plan hash value: 3014579657 ----------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | 40 | 6 (67)| 00:00:01 | | 1 | SORT UNIQUE | | 2 | 40 | 6 (67)| 00:00:01 | | 2 | UNION-ALL | | | | | | | 3 | TABLE ACCESS BY INDEX ROWID| EMP_BK | 1 | 20 | 2 (0)| 00:00:01 | |* 4 | INDEX RANGE SCAN | IDX_EMP_EMPNO | 1 | | 1 (0)| 00:00:01 | | 5 | TABLE ACCESS BY INDEX ROWID| EMP_BK | 1 | 20 | 2 (0)| 00:00:01 | |* 6 | INDEX RANGE SCAN | IDX_EMP_ENAME | 1 | | 1 (0)| 00:00:01 | ----------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("EMPNO"=7788) 6 - access("ENAME"='SCOTT') Note ----- - dynamic sampling used for this statement (level=2) 23 rows selected. Elapsed: 00:00:00.01 10:28:13 SQL> Select Name ,Value From v$parameter Where Name ='_b_tree_bitmap_plans' ; NAME VALUE ------------------------------ --------------------------------------------------------------- _b_tree_bitmap_plans FALSE Elapsed: 00:00:00.02 10:34:06 SQL> alter session set "_b_tree_bitmap_plans" = true; Session altered. Elapsed: 00:00:00.00 11:19:04 SQL> explain plan for select /*+ opt_param('_b_tree_bitmap_plans', 'false') */ empno,ename from emp_bk where empno=7788 or ename='SCOTT'; Explained. Elapsed: 00:00:00.08 11:19:22 SQL> select * from table(dbms_xplan.display); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Plan hash value: 370270337 ---------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 20 | 3 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| EMP_BK | 1 | 20 | 3 (0)| 00:00:01 | ---------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("EMPNO"=7788 OR "ENAME"='SCOTT') Note ----- - dynamic sampling used for this statement (level=2) 17 rows selected. Elapsed: 00:00:00.24 由实验可以看出,false后,false,执行计划也完全不同。一.5 Native Full Outer Join
关于这个特性可以参考如下文章: [b]http://blog.itpub.net/26736162/viewspace-1660038/ 我们在http://blog.itpub.net/26736162/viewspace-1652985/)中总结了一下null值得处理。一.6.1 情形一:
若子查询中的结果中包含null值,那么not in(null、xx、bb、cc)返回为空。 [oracle@rhel6_lhr ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.3.0 Production on Mon May 18 13:38:09 2015 Copyright (c) 1982, 2011, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, Automatic Storage Management, OLAP, Data Mining and Real Application Testing options 13:38:09 SQL> drop table lhr.emp_bk; Table dropped. Elapsed: 00:00:04.16 13:38:15 SQL> create table lhr.emp_bk as select * from scott.emp; Table created. Elapsed: 00:00:00.77 13:41:01 SQL> create table lhr.dept_bk as select * from scott.dept; Table created. Elapsed: 00:00:00.13 13:41:43 SQL> insert into lhr.dept_bk values(50,'lhr','China'); 1 row created. Elapsed: 00:00:00.03 13:41:57 SQL> select * from lhr.dept_bk ; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON 50 lhr China Elapsed: 00:00:00.01 13:42:48 SQL> select * from lhr.emp_bk b; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- ------------------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 1980-12-17 00:00:00 20800 20 7499 ALLEN SALESMAN 7698 1981-02-20 00:00:00 31600 300 30 7521 WARD SALESMAN 7698 1981-02-22 00:00:00 31250 500 30 7566 JONES MANAGER 7839 1981-04-02 00:00:00 22975 20 7654 MARTIN SALESMAN 7698 1981-09-28 00:00:00 31250 1400 30 7698 BLAKE MANAGER 7839 1981-05-01 00:00:00 32850 30 7782 CLARK MANAGER 7839 1981-06-09 00:00:00 12450 10 7788 SCOTT ANALYST 7566 1987-04-19 00:00:00 23000 20 7839 KING PRESIDENT 1981-11-17 00:00:00 15000 10 7844 TURNER SALESMAN 7698 1981-09-08 00:00:00 31500 0 30 7876 ADAMS CLERK 7788 1987-05-23 00:00:00 21100 20 7900 JAMES CLERK 7698 1981-12-03 00:00:00 30950 30 7902 FORD ANALYST 7566 1981-12-03 00:00:00 23000 20 7934 MILLER CLERK 7782 1982-01-23 00:00:00 11300 10 16 rows selected. Elapsed: 00:00:00.02 13:44:00 SQL> select * from lhr.dept_bk a where a.deptno not in(select b.deptno from lhr.emp_bk b); DEPTNO DNAME LOC ---------- -------------- ------------- 50 lhr China 40 OPERATIONS BOSTON Elapsed: 00:00:00.93 13:44:07 SQL> update lhr.emp_bk b set b.deptno=null where empno=7788; 1 row updated. Elapsed: 00:00:00.04 13:45:17 SQL> select * from lhr.emp_bk b; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- ------------------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 1980-12-17 00:00:00 20800 20 7499 ALLEN SALESMAN 7698 1981-02-20 00:00:00 31600 300 30 7521 WARD SALESMAN 7698 1981-02-22 00:00:00 31250 500 30 7566 JONES MANAGER 7839 1981-04-02 00:00:00 22975 20 7654 MARTIN SALESMAN 7698 1981-09-28 00:00:00 31250 1400 30 7698 BLAKE MANAGER 7839 1981-05-01 00:00:00 32850 30 7782 CLARK MANAGER 7839 1981-06-09 00:00:00 12450 10 7788 SCOTT ANALYST 7566 1987-04-19 00:00:00 23000 7839 KING PRESIDENT 1981-11-17 00:00:00 15000 10 7844 TURNER SALESMAN 7698 1981-09-08 00:00:00 31500 0 30 7876 ADAMS CLERK 7788 1987-05-23 00:00:00 21100 20 7900 JAMES CLERK 7698 1981-12-03 00:00:00 30950 30 7902 FORD ANALYST 7566 1981-12-03 00:00:00 23000 20 7934 MILLER CLERK 7782 1982-01-23 00:00:00 11300 10 14 rows selected. Elapsed: 00:00:00.14 13:45:23 SQL> select * from lhr.dept_bk a where a.deptno not in(select b.deptno from lhr.emp_bk b); no rows selected Elapsed: 00:00:00.00 13:45:39 SQL> select * from lhr.dept_bk a where a.deptno not in(select b.deptno from lhr.emp_bk b where b.deptno is not null); DEPTNO DNAME LOC ---------- -------------- ------------- 50 lhr China 40 OPERATIONS BOSTON Elapsed: 00:00:00.04 13:46:01 SQL>一.6.2 情形二:
要求返回所有比“相关文章推荐
- 【书评:Oracle查询优化改写】第三章
- 【书评:Oracle查询优化改写】第三章
- 【书评:Oracle查询优化改写】第三章
- 【书评:Oracle查询优化改写】第14章 结尾章
- 【书评:Oracle查询优化改写】第五至十三章
- 【书评:Oracle查询优化改写】第二章
- 【书评:Oracle查询优化改写】第四章
- 【书评:Oracle查询优化改写】第四章
- 【书评:Oracle查询优化改写】第二章
- Oracle优化查询改写(第三章-操作多个表)
- 【书评:Oracle查询优化改写】第四章
- 【书评:Oracle查询优化改写】第14章 结尾章
- 【书评:Oracle查询优化改写】第二章
- 【书评:Oracle查询优化改写】第四章
- 【书评:Oracle查询优化改写】第14章 结尾章
- Oracle优化查询改写(第一章-单表查询)
- Oracle 查询优化改写
- Oracle优化查询改写(第四章-插入,更新与删除)
- oracle 查询优化及sql改写
- Oracle查询优化改写-笔记