目录是索引的一个最好的例子,每条目录包含对应章节的标题和页码,类比索引的每条索引项包含了数据记录的某些键值组合并包含了对应数据块的访问路径(rowid)。目录的存在就是为了快速定位到感兴趣的内容,索引的存在也是问了加快对表数据的随机访问。
常常被提及的索引可能有单键索引、组合索引、唯一索引、B-Tree索引、位图索引、函数索引、全局索引、局部索引等等。这里只是列举出镜率较高的索引类型,并没有去做严格的划分,各类型间有重叠,比如函数索引可以是B-Tree索引也可以是位图索引。在Oracle中索引和表一样属于逻辑结构中的段(segment)。每个索引都拥有独立的结构,无论是从物理结构还是逻辑结构来看与其所关联的表完全分开,即便索引失效也不会造成原有SQL无法执行,只是改变了执行计划,降低了执行效率。
B-Tree索引
- B-Tree索引包含根节点(Root Node)、分支节点(Branch Node)和叶子节点(Leaf Node)。
- 索引树高度一般都很低,上百亿记录的索引树的高度也只有5,6层。
- 索引本身有序。叶子节点是一个双向链表,因此可以按照索引的升序或降序进行索引扫描。
- 索引项包含键值信息和ROWID。索引项由索引头部、索引列的长度、索引值以及对应记录的rowid。其中唯一索引对应的rowid是唯一的,非唯一索引对应的rowid是可能有多个(多个rowid是有序的)。
- 索引列值全部为NULL的索引项是不会被记录的。
B-Tree索引简要分析
一、提高查询效率
- create index index_col1 on test_index_t1(col1);
create index index_col1 on test_index_t1(col1);再次执行查询的执行计划如下:
未建立索引时执行计划是TABLE ACCESS FULL用时1100ms,建立索引后执行计划是INDEX RANGE SCAN用时90ms,效率提高了10倍以上。这里test_index_t1的数据量不大。如果是大数据量的表执行效率的差距会更加明显。
二、索引树高度较低
- SELECT
- index_name,
- blevel,
- leaf_blocks,
- num_rows,
- distinct_keys,
- clustering_factor
- FROM
- user_ind_statistics
- WHERE
- table_name = UPPER(‘test_index_t1’);
SELECT index_name, blevel, leaf_blocks, num_rows, distinct_keys, clustering_factor FROM user_ind_statistics WHERE table_name = UPPER('test_index_t1');
对于200w条记录的表test_index_t1执行索引统计信息查询后得到的结果为:
三、索引包含键值
- create index index_col1_col2 on test_index_t1(col1, col2);
create index index_col1_col2 on test_index_t1(col1, col2);1. 执行sql
- select col1 from test_index_t1 where col1 between 10 and 20;
select col1 from test_index_t1 where col1 between 10 and 20;
- select col1, col2 from test_index_t1 where col1 between 10 and 20;
select col1, col2 from test_index_t1 where col1 between 10 and 20;
- select * from test_index_t1 where col1 between 10 and 20;
select * from test_index_t1 where col1 between 10 and 20;
四、索引本身有序
- select col1, col2 from test_index_t1 where col1 between 10 and 20 order by col1;
select col1, col2 from test_index_t1 where col1 between 10 and 20 order by col1;
五、索引不保存索引键值全部为NULL的记录
这个特点跟count,sum/avg,max/min的执行计划息息相关,可以总结为以下两点:- COUNT/SUM/AVG必须在索引列为非空的情况下才可以走到索引。(建表是列指定为Not Null或为主键或在where条件中指明为is not null)。
- MIN/MAX则不会受到空值的影响,均能走到索引。
- select count(1) from test_index_t1;
select count(1) from test_index_t1;
<iframe id="tmp_downloadhelper_iframe" style="display: none;"></iframe></div>
</div>
目录是索引的一个最好的例子,每条目录包含对应章节的标题和页码,类比索引的每条索引项包含了数据记录的某些键值组合并包含了对应数据块的访问路径(rowid)。目录的存在就是为了快速定位到感兴趣的内容,索引的存在也是问了加快对表数据的随机访问。
常常被提及的索引可能有单键索引、组合索引、唯一索引、B-Tree索引、位图索引、函数索引、全局索引、局部索引等等。这里只是列举出镜率较高的索引类型,并没有去做严格的划分,各类型间有重叠,比如函数索引可以是B-Tree索引也可以是位图索引。在Oracle中索引和表一样属于逻辑结构中的段(segment)。每个索引都拥有独立的结构,无论是从物理结构还是逻辑结构来看与其所关联的表完全分开,即便索引失效也不会造成原有SQL无法执行,只是改变了执行计划,降低了执行效率。
B-Tree索引
- B-Tree索引包含根节点(Root Node)、分支节点(Branch Node)和叶子节点(Leaf Node)。
- 索引树高度一般都很低,上百亿记录的索引树的高度也只有5,6层。
- 索引本身有序。叶子节点是一个双向链表,因此可以按照索引的升序或降序进行索引扫描。
- 索引项包含键值信息和ROWID。索引项由索引头部、索引列的长度、索引值以及对应记录的rowid。其中唯一索引对应的rowid是唯一的,非唯一索引对应的rowid是可能有多个(多个rowid是有序的)。
- 索引列值全部为NULL的索引项是不会被记录的。
B-Tree索引简要分析
一、提高查询效率
- create index index_col1 on test_index_t1(col1);
create index index_col1 on test_index_t1(col1);再次执行查询的执行计划如下:
未建立索引时执行计划是TABLE ACCESS FULL用时1100ms,建立索引后执行计划是INDEX RANGE SCAN用时90ms,效率提高了10倍以上。这里test_index_t1的数据量不大。如果是大数据量的表执行效率的差距会更加明显。
二、索引树高度较低
- SELECT
- index_name,
- blevel,
- leaf_blocks,
- num_rows,
- distinct_keys,
- clustering_factor
- FROM
- user_ind_statistics
- WHERE
- table_name = UPPER(‘test_index_t1’);
SELECT index_name, blevel, leaf_blocks, num_rows, distinct_keys, clustering_factor FROM user_ind_statistics WHERE table_name = UPPER('test_index_t1');
对于200w条记录的表test_index_t1执行索引统计信息查询后得到的结果为:
三、索引包含键值
- create index index_col1_col2 on test_index_t1(col1, col2);
create index index_col1_col2 on test_index_t1(col1, col2);1. 执行sql
- select col1 from test_index_t1 where col1 between 10 and 20;
select col1 from test_index_t1 where col1 between 10 and 20;
- select col1, col2 from test_index_t1 where col1 between 10 and 20;
select col1, col2 from test_index_t1 where col1 between 10 and 20;
- select * from test_index_t1 where col1 between 10 and 20;
select * from test_index_t1 where col1 between 10 and 20;
四、索引本身有序
- select col1, col2 from test_index_t1 where col1 between 10 and 20 order by col1;
select col1, col2 from test_index_t1 where col1 between 10 and 20 order by col1;
五、索引不保存索引键值全部为NULL的记录
这个特点跟count,sum/avg,max/min的执行计划息息相关,可以总结为以下两点:- COUNT/SUM/AVG必须在索引列为非空的情况下才可以走到索引。(建表是列指定为Not Null或为主键或在where条件中指明为is not null)。
- MIN/MAX则不会受到空值的影响,均能走到索引。
- select count(1) from test_index_t1;
select count(1) from test_index_t1;
<iframe id="tmp_downloadhelper_iframe" style="display: none;"></iframe></div>
</div>