INDEX_JOIN
这里就以INDEX_JOIN为例,简单描述一下如何影响Oracle的执行计划的产生。
控制执行计划最简单的方法莫过于使用HINT,这篇文章要介绍的是,在不使用HINT的情况下,让Oracle产生INDEX_JOIN执行计划。
下面先构造查询所用的表,问题中使用的表是HR用户下的EMPLOYEES。如果hr用户不存在,Oracle9i可以通过$ORACLE_HOME/demo/schema/human_resources/hr_main.sql来创建用户。
SQL> CREATE TABLE EMPLOYEES AS SELECT * FROM HR.EMPLOYEES;
表已创建。
SQL> SELECT COUNT(*) FROM EMPLOYEES;
COUNT(*)
----------
107
已选择 1 行。
查询语句为:
SQL> SET AUTOT TRACE
SQL> SELECT EMPLOYEE_ID, SALARY
2 FROM EMPLOYEES
3 WHERE SALARY > 2000;
已选择107行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (FULL) OF 'EMPLOYEES'
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
12 consistent gets
0 physical reads
0 redo size
2273 bytes sent via SQL*Net to client
580 bytes received via SQL*Net from client
9 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
107 rows processed
需要采用索引连接,首先将两个索引建立起来。而且索引连接是CBO才能采用的执行计划,因此对表和索引进行分析。
SQL> ALTER TABLE EMPLOYEES ADD CONSTRAINT PK_EMPLOYEES PRIMARY KEY (EMPLOYEE_ID);
表已更改。
SQL> CREATE INDEX IND_EMP_SALARY ON EMPLOYEES (SALARY);
索引已创建。
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'EMPLOYEES', CASCADE => TRUE)
PL/SQL 过程已成功完成。
再次执行上面的SQL:
SQL> SELECT EMPLOYEE_ID, SALARY
2 FROM EMPLOYEES
3 WHERE SALARY > 2000;
已选择107行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=107 Bytes=856)
1 0 TABLE ACCESS (FULL) OF 'EMPLOYEES' (Cost=2 Card=107 Bytes=856)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
12 consistent gets
0 physical reads
0 redo size
2273 bytes sent via SQL*Net to client
580 bytes received via SQL*Net from client
9 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
107 rows processed
Oracle执行的仍然是全表扫描,但是优化器以及是CBO了。先通过HINT,看看现在是否已经满足了INDEX_JOIN执行计划的执行条件:
SQL> SELECT /*+ INDEX_JOIN(EMPLOYEES PK_EMPLOYEES IND_EMP_SALARY) */
2 EMPLOYEE_ID, SALARY
3 FROM EMPLOYEES
4 WHERE SALARY > 2000;
已选择107行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=4 Card=107 Bytes=856)
1 0 VIEW OF 'index$_join$_001' (Cost=4 Card=107 Bytes=856)
2 1 HASH JOIN
3 2 INDEX (RANGE SCAN) OF 'IND_EMP_SALARY' (NON-UNIQUE) (Cost=3 Card=107 Bytes=856)
4 2 INDEX (FAST FULL SCAN) OF 'PK_EMPLOYEES' (UNIQUE) (Cost=3 Card=107 Bytes=856)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
12 consistent gets
0 physical reads
0 redo size
2273 bytes sent via SQL*Net to client
580 bytes received via SQL*Net from client
9 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
107 rows processed
现在Oracle执行INDEX_JOIN的条件已经满足,Oracle之所以没有选择INDEX_JOIN而选择全表扫描,是因为Oracle认为全表扫描的代价比INDEX_JOIN要低。
不使用HINT,而让Oracle选择INDEX_JOIN,就必须让Oracle认为全表扫描的代价比INDEX_JOIN要高。
最直接的办法是修改Oracle收集的统计信息,通过这种方法来使Oracle认为表扫描的搭建远远大于通过索引连接的代价。
SQL> SELECT NUM_ROWS, BLOCKS FROM USER_TABLES WHERE TABLE_NAME = 'EMPLOYEES';
NUM_ROWS BLOCKS
---------- ----------
107 2
现在的统计信息显示,全部数据存储在两个BLOCK中,Oracle当然认为全部扫描的代价低,如果设置表统计信息中BLOCK的数量很大,Oracle就会认识到全表扫描的代价比较大。
SQL> EXEC DBMS_STATS.SET_TABLE_STATS(USER, 'EMPLOYEES', NUMROWS => 100, NUMBLKS => 100)
PL/SQL 过程已成功完成。
SQL> SELECT EMPLOYEE_ID, SALARY
2 FROM EMPLOYEES
3 WHERE SALARY > 2000;
已选择107行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=4 Card=100 Bytes=800)
1 0 VIEW OF 'index$_join$_001' (Cost=4 Card=100 Bytes=800)
2 1 HASH JOIN
3 2 INDEX (RANGE SCAN) OF 'IND_EMP_SALARY' (NON-UNIQUE) (Cost=3 Card=100 Bytes=800)
4 2 INDEX (FAST FULL SCAN) OF 'PK_EMPLOYEES' (UNIQUE) (Cost=3 Card=100 Bytes=800)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
12 consistent gets
0 physical reads
0 redo size
2273 bytes sent via SQL*Net to client
580 bytes received via SQL*Net from client
9 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
107 rows processed
通过设置Oracle的统计信息的方法,让目标执行计划的代价最小,从而使得Oracle选择了预期的执行计划。
转载 http://yangtingkun.itpub.net/post/468/357542
INDEX_JOIN相关推荐
- Oracle的SQL语法提示30例,INDEX_JOIN,ORDERED,USE_NL,LEADING
在SQL语句优化过程中,我们经常会用到hint,现总结一下在SQL优化过程中常见Oracle HINT的用法: 1. /*+ALL_ROWS*/ 表明对语句块选择基于开销的优化方法,并获得最佳吞吐量, ...
- Oracle常用傻瓜问题1000问
1. Oracle安装完成后的初始口令? internal/oracle sys/change_on_install system/manager scott/tiger sysman/oem_tem ...
- Oracle中Hint深入理解(原创)
http://czmmiao.iteye.com/blog/1478465 Hint概述 基于代价的优化器是很聪明的,在绝大多数情况下它会选择正确的优化器,减轻了DBA的负担.但有时它也聪明反被聪明 ...
- Oracle Hints具体解释
在向大家具体介绍Oracle Hints之前,首先让大家了解下Oracle Hints是什么,然后全面介绍Oracle Hints,希望对大家实用.基于代价的优化器是非常聪明的,在绝大多数情况下它会选 ...
- Oracle語句大全
1. Oracle安装完成后的初始口令? internal/oracle sys/change_on_install system/manager scott/tiger sysman/oem_tem ...
- ORACLE选择hint,ORACLE中的的HINT详解
hints是oracle提供的一种机制,用来告诉优化器按照我们的告诉它的方式生成执行计划.我们可以用hints来实现: 1) 使用的优化器的类型 2) 基于代价的优化器的优化目标,是all_rows还 ...
- 关于Oracle数据库19c中的关键字和保留字的说明
关于Oracle数据库中的关键字和保留字的说明 官方文档节选: You cannot use Oracle SQL reserved words as nonquoted identifiers. ...
- 下拉框选中事件ajax,LayUI中select下拉框选中触发事件
SpringMvc的数据绑定流程 在SpringMvc中会将来自web页面的请求和响应数据与controller中对应的处理方法的入参进行绑定,即数据绑定.流程如下: -1.SpringMvc主框架将 ...
- 常见Oracle HINT的用法
1. /*+ALL_ROWS*/ 表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化. 例如: SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_I ...
最新文章
- @HostListener 可接收的事件列表
- 【AI初识境】深度学习模型中的Normalization,你懂了多少?
- 如何在html中添加选择列表,html – 如何在选择列表中添加图像
- db2主键自增和oracle,oracle_浅析常用数据库的自增字段创建方法汇总,DB2复制代码 代码如下:CREATEnbsp - phpStudy...
- mysql练习数据_数据分析学习第一关-入门
- GoLang:你真的了解 HTTPS 吗?
- 藤条生长为字母的动画
- 基于Android的聊天软件,Socket即时通信,实现用户在线聊天
- python生成html表格
- OC学习笔记四 数据类型
- python音乐推荐系统_音乐推荐系统
- GB50311-2016标准综合布线
- [图文并茂]手把手教你用`U盘启动盘`重装Windows系统
- Nginx 配置子域名
- python实现位置定位_python定位位置
- 做视频自媒体必备的工具,手机电脑端都有哦
- 元宇宙技术在几年后质变,迎来体验终端世界
- 串口转无线WiFi模块——WizFi210-EVB操作手册
- linux c语言编译成exe,C/C++程序从编译到最终生成可执行文件的过程分析
- 【开源】司马编译器 Smart Compiler 符号表
热门文章
- python怎么建文件dome_Python专题(四) 如何制作一个demo给老板看
- python登录网站后爬取数据_用 Python 登录主流网站,我们的数据爬取少不了它
- python 调用class不指定函数_python调用另一个.py中的类或函数
- 计算机专业毕业论文的参考文献,计算机专业毕业专著类参考文献 计算机专业毕业论文参考文献哪里找...
- java规则计算_java实现的霍纳规则的多项式计算
- matlab分类器设计,简单分类器的MATLAB实现.doc
- java script jquery_Java Script 学习笔记 -- jQuery
- Spark详解(十四):Spark SQL的Join实现
- Netty详解(五):Netty TCP粘包 拆包
- Java设计模式(五):单例设计模式