Oracle 查询优化器 -- 访问路径
2015-07-17 22:01
417 查看
-- Start
DB_FILE_MULTIBLOCK_READ_COUNT 定义的值。
如果你想让 Oracle 使用全表扫描,你也可以通过下面的方式指示 Oracle 使用全表扫描。
factor)来衡量这种特性。索引聚簇因子越高,表明 Oracle 通过 Rowid 访问行的代价就越高。此外,Oracle 会根据索引类型的不同,是否排序,采用不同的索引扫描方式。
而你的查询语句没有用到索引的第一列 gender,只用到了第二列 email, 如下所示。
由于性别列(gender)只有男女两个值,Oracle 会采用如下的方式做查询。
Oracle 把这种查询方式叫做索引跳跃扫描,需要注意的是这种方式只适合像性别这样,值非常少的列,你也可以通过下面的方式建议 Oracle 采用索引跳跃扫描。
--更多参见:Oracle SQL 优化精萃
-- 声明:转载请注明出处
-- Last edited on 2015-08-28
-- Created by ShangBo on 2015-07-17
-- End
全表扫描(full table scans)
不要以为全表扫描就一定慢, 全表扫描时, 由于数据块在磁盘中是连续的,Oracle 可以一次读取多个块来提高查询效率,至于多少个块,是由 DB_FILE_MULTIBLOCK_READ_COUNT 决定的。所以,如果你需要返回一个表的大部分数据,全表扫描要比索引扫描快。除此之外,Oracle 会自动对小表进行全表扫描,那什么是小表呢?就是语句块小于DB_FILE_MULTIBLOCK_READ_COUNT 定义的值。
如果你想让 Oracle 使用全表扫描,你也可以通过下面的方式指示 Oracle 使用全表扫描。
select /* FULL(t)*/ * from test t where col = 'test';
索引扫描(index scans)
你有没有想过,我们通过索引扫描时,如何通过索引定位到表中的位置呢?答案是通过 Rowid, Rowid 是 Oracle 内部使用的,用来标示行存储地址,所以通过 Rowid 定位行记录是最快的。有一点特别需要注意,Oracle 读写磁盘的最小单位是块,一个块可能包含多行,所以全表扫描还是索引扫描取决于访问块的百分比,而不是行的百分比。假设我们现在需要访问 3 行,这 3 行可能在一个块中,也可能在两个块中,还可能在三个块中,很明显,最理想的情况是在一个块中,Oracle 使用索引聚簇因子(index clusteringfactor)来衡量这种特性。索引聚簇因子越高,表明 Oracle 通过 Rowid 访问行的代价就越高。此外,Oracle 会根据索引类型的不同,是否排序,采用不同的索引扫描方式。
唯一索引扫描(Index Unique Scans)
如果你的查询条件有等价操作符(=),且恰好能用到唯一索引,那么 Oracle 会采用唯一索引扫描,当然你也可以通过下面的方式建议 Oracle 采用哪个索引。select /* INDEX(t test_id_pk)*/ * from test t where col = 'test';
索引范围扫描(Index Range Scans)
如果你的查询条件有范围操作符(>,>=,<,<=,like 'abc%'),且恰好能用到索引,那么 Oracle 会采用索引范围扫描,当然你也可以通过下面的方式建议 Oracle 采用哪个索引。select /* INDEX(t test_id_pk)*/ * from test t where col = 'test';
索引降序范围扫描(Index Range Scans Descending)
如果你的查询条件有范围操作符且要求用索引列排序,那么 Oracle 会采用索引降序范围扫描,这样做的好处是 Oracle 可以省略排序这个非常耗时的步骤。当然你也可以通过下面的方式建议 Oracle 采用索引降序范围扫描。如果你的索引是升序的。 select /* INDEX_DESC(t test_id_pk)*/ * from test t where col = 'test'; 如果你的索引是降序的。 select /* INDEX_ASC(t test_id_pk)*/ * from test t where col = 'test';
索引跳跃扫描(Index Skip Scans)
如果你的索引是复合索引,也就是索引包含多个列,如下所示。CREATE INDEX cust_idx ON customers (gender, email);
而你的查询语句没有用到索引的第一列 gender,只用到了第二列 email, 如下所示。
SELECT * FROM customers WHERE email = 'wave0409@163.com';
由于性别列(gender)只有男女两个值,Oracle 会采用如下的方式做查询。
SELECT * FROM customers WHERE gender='M' AND email = 'wave0409@163.com'; UNION ALL SELECT * FROM customers WHERE gender='F' AND email = 'wave0409@163.com';
Oracle 把这种查询方式叫做索引跳跃扫描,需要注意的是这种方式只适合像性别这样,值非常少的列,你也可以通过下面的方式建议 Oracle 采用索引跳跃扫描。
select /* INDEX_SS(t test_id_idx)*/ * from test t where col = 'test'; select /* INDEX_SS_ASC(t test_id_idx)*/ * from test t where col = 'test'; select /* INDEX_SS_DESC(t test_id_idx)*/ * from test t where col = 'test';
全索引扫描(Full Scans)
如果你的查询需要排序或分组,且排序或分组用到的列恰好是索引列,那么 Oracle 会采用全索引扫描,由于索引列是有序的,这样 Oracle 可以省略排序这个非常耗时的步骤。快速全索引扫描(Fast Full Index Scans)
如果你要查询的所有列都包含在索引中,Oracle 就不需要访问表了,这样 Oracle 就可能通过并行和一次读取多个块来提高查询索引的效率。你也可以通过下面的方式建议 Oracle 采用快速全索引扫描。select /* INDEX_FFS(t test_id_pk)*/ * from test t where col = 'test';
索引连接扫描(Index Joins)
如果你的表有多个索引,恰好你要查询的所有列包含在这些索引中,Oracle 就不需要访问表了,Oracle 只需要把这些索引连接起来。你也可以通过下面的方式建议 Oracle 采用索引连接。select /* INDEX_JOIN(t test_id_idx test_name_idx)*/ * from test t where col = 'test';
位图索引扫描(Bitmap Indexes)
如果你的表定义了位图索引,Oracle 会使用位图索引来做查询,你也可以通过下面的方式建议 Oracle 采用位图索引扫描。select /* INDEX_COMBINE(t test_idx1 test_idx2)*/ * from test t where col = 'test';
索引聚簇扫描(Indexed Cluster Access)
如果你的表包含在了某个索引聚簇中,Oracle 会使用索引聚簇来执行查询。Hash 聚簇扫描(Hash Cluster Access)
如果你的表包含在了某个Hash 聚簇中,Oracle 会使用 Hash 聚簇来执行查询。采样扫描(Sample Table Scans)
如果你的查询语句包含 SAMPLE 子句,那么 Oracle 会使用 采样扫描。--更多参见:Oracle SQL 优化精萃
-- 声明:转载请注明出处
-- Last edited on 2015-08-28
-- Created by ShangBo on 2015-07-17
-- End
相关文章推荐
- Oracle 定义变量总结
- Oracle和SQL SERVER在SQL语句上的差别
- oracle看到用户的所有表名、表睐、字段名称、现场的目光、是空的、字段类型
- ORACLE 11g安装中vnc viewer黑屏现象
- Oracle 11g 环境,使用utl_smtp创建一个存储过程来发送邮件
- Oracle分析函数
- Oracle 中的 TO_DATE 和 TO_CHAR 函数 日期处理
- 怎么将oracle的sql文件转换成mysql的sql文件-- 费元星
- oracle 创建link 报 ora-01017错误
- Oracle登录方法
- oracle正则表达式函数和正则表达式简介
- oracle操作一些常识
- 诊断并解决 ORA-4030 错误 (Doc ID 1548826.1)
- oracle日期函数
- cx_Oracle install
- 问题-Delphi为什么不能连接oracle
- 问题-delphi无法编辑oracle表
- 用Oracle序列当主键
- Oracle TO_DATE 日期格式
- oracle 存储过程的基本语法