B树索引

简介

B树索引是Oracle默认索引,B树索引可以提高SQL语句的性能,强制执行主键和唯一键约束的唯一性,减少通过主键和外键约束关联的父表和子表间潜在都锁定问题。

创建索引步骤

  • 估算索引大小
  • 指定表空间
  • 允许对象从他们的表空间继承存储参数
  • 定义创建索引要使用的命名标准

索引的创建

创建数据表空间

create tablespace reporting_data  datafile '+DATA/reporting_data01.dbf'  size 1G  extent management local  uniform size 1M  segment space management auto;

创建索引表空间

create tablespace reporting_index  datafile '+DATA/reporting_index01.dbf'  size 500M  extent management local  uniform size 128K  segment space management auto  nologging;

创建表,并指定表空间

CREATE TABLE cust( cust_id    NUMBER,last_name  VARCHAR2(30),first_name VARCHAR2(30))TABLESPACE reporting_data;

创建索引并指定索引表空间

create index cust_idx1 on cust(last_name) tablespace reporting_index online;

对于新创建的表,进行一次统计信息收集

SQL> exec dbms_stats.gather_table_stats(ownname=>'testidx',tabname=>'CUST',cascade=>true);PL/SQL procedure successfully completed.

配置主键

ALTER TABLE cust ADD CONSTRAINT cust_pk PRIMARY KEY (cust_id) USING INDEX TABLESPACE reporting_index;

配置唯一性约束

ALTER TABLE cust ADD CONSTRAINT cust_uk1 UNIQUE (last_name, first_name) USING INDEX TABLESPACE reporting_index;

创建地址表,并指定表空间

CREATE TABLE address( address_id NUMBER,cust_id    NUMBER,street     VARCHAR2(30),city       VARCHAR2(30),state      VARCHAR2(30))TABLESPACE reporting_data;

给地址表添加外键约束,外键索引对应cust表的cust_id列

ALTER TABLE address ADD CONSTRAINT addr_fk1 FOREIGN KEY (cust_id) REFERENCES cust(cust_id);

创建address表的外键索引

CREATE INDEX addr_fk1 ON address(cust_id) TABLESPACE reporting_index;

报告索引

set linesize 300col index_name for a30col INDEX_TYPE for a10col TABLE_NAME for a20col TABLESPACE_NAME for a30col status for a20select index_name, index_type, table_name, tablespace_name, statusfrom user_indexeswhere table_name in ('CUST','ADDRESS');INDEX_NAME                     INDEX_TYPE TABLE_NAME                     TABLESPACE_NAME                                             STATUS------------------------------ ---------- ------------------------------ ----------------------------------------------------------- ------------------------CUST_IDX1                      NORMAL     CUST                           REPORTING_INDEX                                             VALIDCUST_PK                        NORMAL     CUST                           REPORTING_INDEX                                             VALIDCUST_UK1                       NORMAL     CUST                           REPORTING_INDEX                                             VALIDADDR_FK1                       NORMAL     ADDRESS                        REPORTING_INDEX                                             VALID
col index_name for a30col column_name for a30col column_position for 99999999999999select index_name, column_name, column_positionfrom user_ind_columnswhere table_name in ('CUST','ADDRESS')order by index_name, column_position;SQL> col index_name for a30SQL> col column_name for a30SQL> col column_position for 99999999999999SQL> select index_name, column_name, column_position  2  from user_ind_columns  3  where table_name in ('CUST','ADDRESS')  4  order by index_name, column_position;INDEX_NAME                     COLUMN_NAME                    COLUMN_POSITION------------------------------ ------------------------------ ---------------ADDR_FK1                       CUST_ID                                      1CUST_IDX1                      LAST_NAME                                    1CUST_PK                        CUST_ID                                      1CUST_UK1                       LAST_NAME                                    1CUST_UK1                       FIRST_NAME                                   2
col segment_name for a30col segment_type for a30col extents for 999999999999col bytes for 999999999999select a.segment_name, a.segment_type, a.extents, a.bytesfrom user_segments a, user_indexes  bwhere a.segment_name = b.index_nameand   b.table_name in ('CUST','ADDRESS');SQL> col segment_name for a30SQL> col segment_type for a30SQL> col extents for 999999999999SQL> col bytes for 999999999999SQL> SQL> select a.segment_name, a.segment_type, a.extents, a.bytes  2  from user_segments a, user_indexes  b  3  where a.segment_name = b.index_name  4  and   b.table_name in ('CUST','ADDRESS');SEGMENT_NAME                   SEGMENT_TYPE                         EXTENTS         BYTES------------------------------ ------------------------------ ------------- -------------CUST_IDX1                      INDEX                                      1        131072CUST_PK                        INDEX                                      1        131072CUST_UK1                       INDEX                                      1        131072

索引场景简介

当向表中插入行时,Oracle将分配由无路数据库块组成的区,Oracle还将为索引分配块,对于每个插入到表中的记录,Oracle还将创建一个包含Rowid和列值的索引条目。
每个索引项的rowid指向存储该表的列值的数据文件和块。

当从一个表及其对应的索引选择数据时,有三种情况

  • SQL查询所需要的所有表的数据都在索引中,因此只需要访问索引块,不需要从表中读取块。
  • 查询所需的所有信息没有都包含在索引块中,因此查询优化器选择既访问索引块也访问表块来检索需要的数据,以满足查询的结果。
  • 查询优化器选择不访问索引。因此只访问表块。

场景一:所有数据位于索引块。

有两种情况,在每种情况下,执行查询需要的所有数据,包括返回给用户的数据,以及在where字句中被评估的数据,都位于该索引。- 索引范围扫描(index range scan) :如果优化器确定它使用索引结构检索查询所需的多个行是有效的,那么就使用这种索引。 索引范围扫描被广泛应用在各种各样的情况- 索引快速全扫描(index fast full scan)如果优化器确定表中大部分行所需要进行检索,那么就使用这种扫描。但是所有需要的信息都存储在索引中。由于索引结构通常比表结构小,优化器确定全索引扫描(比全表扫描)更高效。这种情况对于统计(count)值的查询比较常见

演示1 索引范围扫描

场景二: 索引中不包含所有信息

场景三: 只有表被访问信息

在创建前估算索引表大小

显示创建索引的代码

删除B树索引

管理带约束的B树索引

输入一个模式,查询是否存在相应的外键约束

set linesize 300col CHECKER for a20col INDEX_TYPE for a20col OWNER for a20col TABLE_NAME for a20col INDEX_NAME for a20col CONSTRAINT_NAME for a20col COLS for a20SELECT CASE WHEN ind.index_name IS NOT NULL THEN   CASE WHEN ind.index_type IN ('BITMAP') THEN     '** Bitmp idx **'   ELSE     'indexed'   END ELSE   '** Check idx **' END checker,ind.index_type,cons.owner, cons.table_name, ind.index_name, cons.constraint_name, cons.colsFROM (SELECT        c.owner, c.table_name, c.constraint_name       ,LISTAGG(cc.column_name, ',' ) WITHIN GROUP (ORDER BY cc.column_name) cols      FROM dba_constraints  c          ,dba_cons_columns cc      WHERE c.owner           = cc.owner      AND   c.owner = UPPER('&&schema')      AND   c.constraint_name = cc.constraint_name      AND   c.constraint_type = 'R'      GROUP BY c.owner, c.table_name, c.constraint_name) consLEFT OUTER JOIN(SELECT  table_owner, table_name, index_name, index_type, cbr ,LISTAGG(column_name, ',' ) WITHIN GROUP (ORDER BY column_name) cols FROM (SELECT        ic.table_owner, ic.table_name, ic.index_name       ,ic.column_name, ic.column_position, i.index_type       ,CONNECT_BY_ROOT(ic.column_name) cbr       FROM dba_ind_columns ic           ,dba_indexes     i       WHERE ic.table_owner = UPPER('&&schema')       AND   ic.table_owner = i.table_owner       AND   ic.table_name  = i.table_name       AND   ic.index_name  = i.index_name       CONNECT BY PRIOR ic.column_position-1 = ic.column_position       AND PRIOR ic.index_name = ic.index_name)  GROUP BY table_owner, table_name, index_name, index_type, cbr) indON  cons.cols       = ind.colsAND cons.table_name = ind.table_nameAND cons.owner      = ind.table_ownerORDER BY checker, cons.owner, cons.table_name;set linesize 300col CHECKER for a20col INDEX_TYPE for a20col OWNER for a20col TABLE_NAME for a20col INDEX_NAME for a20col CONSTRAINT_NAME for a20col COLS for a20SQL> SELECT  2   CASE WHEN ind.index_name IS NOT NULL THEN  3     CASE WHEN ind.index_type IN ('BITMAP') THEN  4       '** Bitmp idx **'  5     ELSE  6       'indexed'  7     END  8   ELSE  9     '** Check idx **' 10   END checker 11  ,ind.index_type 12  ,cons.owner, cons.table_name, ind.index_name, cons.constraint_name, cons.cols 13  FROM (SELECT 14          c.owner, c.table_name, c.constraint_name 15         ,LISTAGG(cc.column_name, ',' ) WITHIN GROUP (ORDER BY cc.column_name) cols 16        FROM dba_constraints  c 17            ,dba_cons_columns cc 18        WHERE c.owner           = cc.owner 19        AND   c.owner = UPPER('&&schema') 20        AND   c.constraint_name = cc.constraint_name 21        AND   c.constraint_type = 'R' 22        GROUP BY c.owner, c.table_name, c.constraint_name) cons 23  LEFT OUTER JOIN 24  (SELECT 25    table_owner, table_name, index_name, index_type, cbr 26   ,LISTAGG(column_name, ',' ) WITHIN GROUP (ORDER BY column_name) cols 27   FROM (SELECT 28          ic.table_owner, ic.table_name, ic.index_name 29         ,ic.column_name, ic.column_position, i.index_type 30         ,CONNECT_BY_ROOT(ic.column_name) cbr 31         FROM dba_ind_columns ic 32             ,dba_indexes     i 33         WHERE ic.table_owner = UPPER('&&schema') 34         AND   ic.table_owner = i.table_owner 35         AND   ic.table_name  = i.table_name 36         AND   ic.index_name  = i.index_name 37         CONNECT BY PRIOR ic.column_position-1 = ic.column_position 38         AND PRIOR ic.index_name = ic.index_name) 39    GROUP BY table_owner, table_name, index_name, index_type, cbr) ind 40  ON  cons.cols       = ind.cols 41  AND cons.table_name = ind.table_name 42  AND cons.owner      = ind.table_owner 43  ORDER BY checker, cons.owner, cons.table_name;Enter value for schema: testidxold  19:       AND   c.owner = UPPER('&&schema')new  19:       AND   c.owner = UPPER('testidx')old  33:        WHERE ic.table_owner = UPPER('&&schema')new  33:        WHERE ic.table_owner = UPPER('testidx')CHECKER              INDEX_TYPE           OWNER                TABLE_NAME           INDEX_NAME           CONSTRAINT_NAME      COLS-------------------- -------------------- -------------------- -------------------- -------------------- -------------------- --------------------indexed              NORMAL               TESTIDX              ADDRESS              ADDR_FK1             ADDR_FK1             CUST_ID
©著作权归作者所有:来自51CTO博客作者李石岩的原创作品,如需转载,请注明出处,否则将追究法律责任

每一份赞赏源于懂得

赞赏

0人进行了赞赏支持

更多相关文章

  1. 索引不是越多越好,理解索引结构原理,才有助于我们建立合适的索引!
  2. Kubernetes 部署Redis主从服务(StatefulSet)
  3. jenkins分布式节点添加
  4. Lindorm原理 | Lindorm全文索引技术介绍
  5. python自动创建每周周报模板
  6. Hudi原理 | 在Apache Hudi中为快速更删配置合适的索引原创
  7. Oracle索引整理
  8. gitlab迁移及迁移后500问题
  9. 如何使用iMovie模板创建新预告片?

随机推荐

  1. c语言数据类型转换的方法
  2. c语言中“或”怎么表示?
  3. c语言怎么实现动态内存分配
  4. c语言二进制如何表示
  5. c语言中的关键字有哪些类型?
  6. c语言中long是什么意思
  7. c语言0x什么意思
  8. printf在c语言中什么意思
  9. c语言中void的含义
  10. c语言的基本组成单位是什么