Oralce的性能優化之解析索引的前世此生sql
總結: 在oracle中索引就像一本書的目錄同樣,它能夠加快查詢速度,提升查詢效率。在oracle中對於索引的存儲採用B樹索引來實現,B數索引是樹形結構,存儲時也是帶枝帶葉的。索引分爲根節點,分支節點和葉子節點。性能優化
一>索引的內部信息深究oracle
-----建立表dom
SQL> create table index_test as select * from user_objects; Table created
---在表的字段上建立索引ide
SQL> create index inx_test on index_test(object_id); Index created
---分析表性能
SQL> analyze index inx_test validate structure; Index analyzed
---查看索引的內部信息優化
SQL> select height,blocks,br_blks,lf_blks,lf_rows,del_lf_rows from index_stats; HEIGHT BLOCKS BR_BLKS LF_BLKS LF_ROWS DEL_LF_ROWS ---------- ---------- ---------- ---------- ---------- ----------- 1 8 0 1 48 0 SQL> select count(*) from index_test; COUNT(*) ---------- 48
----隨機抽取幾條數據做爲後續的DML操做基礎spa
SQL> select * from(select object_id from index_test order by dbms_random.value()) where rownum<5; OBJECT_ID ---------- 52647 53095 52646 51151
----選擇第一條記錄,做爲一個update操做orm
SQL> update index_test set object_id=11111 where object_id=52647; 1 row updated
----分析表索引
SQL> analyze index inx_test validate structure; Index analyzed
----查看索引節點內部信息
SQL> select height,blocks,br_blks,lf_blks,lf_rows,del_lf_rows from index_stats; HEIGHT BLOCKS BR_BLKS LF_BLKS LF_ROWS DEL_LF_ROWS ---------- ---------- ---------- ---------- ---------- ----------- 1 8 0 1 49 1 ------嘗試一個Insert操做 SQL> insert into index_test select * from index_test; 48 rows inserted ---分析表 SQL> analyze index inx_test validate structure; Index analyzed ----查看索引節點內部信息 SQL> select height,blocks,br_blks,lf_blks,lf_rows,del_lf_rows from index_stats; HEIGHT BLOCKS BR_BLKS LF_BLKS LF_ROWS DEL_LF_ROWS ---------- ---------- ---------- ---------- ---------- ----------- 1 8 0 1 96 0
二>索引的訪問模式實踐
(1)索引惟一掃描
----建立表
SQL> create table a as select object_id,object_name,object_type from dba_objects; Table created
---查看錶結構
SQL> desc a; Name Type Nullable Default Comments ----------- ------------- -------- ------- -------- OBJECT_ID NUMBER Y OBJECT_NAME VARCHAR2(128) Y OBJECT_TYPE VARCHAR2(19) Y
---分析表
SQL> analyze table a compute statistics; Table analyzed
----建立惟一索引在a表的obkect_id字段上
SQL> create unique index ind_a on a(object_id); Index created SQL> set autot traceonly exp; Cannot SET AUTOT
----執行查詢語句並查看執行計劃
SQL> select * from a where object_id=258; OBJECT_ID OBJECT_NAME OBJECT_TYPE ---------- -------------------------------------------------------------------------------- ------------------- 258 DUAL TABLE SQL> EXPLAIN PLAN FOR select * from a where object_id=258; Explained SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- Plan hash value: 2087649606 -------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time -------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 36 | 2 (0)| 00:00 | 1 | TABLE ACCESS BY INDEX ROWID| A | 1 | 36 | 2 (0)| 00:00 |* 2 | INDEX UNIQUE SCAN | IND_A | 1 | | 1 (0)| 00:00 -------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_ID"=258) 14 rows selected
(2)快速索引全掃描
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 Connected as scott@ORCL SQL> EXPLAIN PLAN FOR select * from a; Explained SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- Plan hash value: 2248738933 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 50858 | 1787K| 73 (3)| 00:00:01 | | 1 | TABLE ACCESS FULL| A | 50858 | 1787K| 73 (3)| 00:00:01 | -------------------------------------------------------------------------- 8 rows selected SQL> select count(*) from a where object_id is null; COUNT(*) ---------- 0 簡單的修改一些列的屬性,排除NULL的干擾,就會走快速索引全掃描. SQL> alter table a nodify(object_id not null); table altered SQL> EXPLAIN PLAN FOR select object_id from a; Explained SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- Plan hash value: 672397539 ------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 50858 | 198K| 26 (4)| 00:00:01 | | 1 | INDEX FAST FULL SCAN| IND_A | 50858 | 198K| 26 (4)| 00:00:01 | ------------------------------------------------------------------------------ 8 rows selected
(3)索引全掃描
SQL> EXPLAIN PLAN FOR select * from a order by object_id; Explained SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- Plan hash value: 3699785968 -------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time -------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 50858 | 1787K| 467 (1)| 00:00 | 1 | TABLE ACCESS BY INDEX ROWID| A | 50858 | 1787K| 467 (1)| 00:00 | 2 | INDEX FULL SCAN | IND_A | 50858 | | 108 (2)| 00:00 -------------------------------------------------------------------------------- 9 rows selected
(4)區間掃描
若是涉及索引列的區間值,能夠使用區間掃描,好比咱們經常使用的between條件就會走區間掃描
SQL> EXPLAIN PLAN FOR select * from a where object_id between 2000 and 2050; Explained SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- Plan hash value: 1070634250 -------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time -------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 46 | 1656 | 3 (0)| 00:00 | 1 | TABLE ACCESS BY INDEX ROWID| A | 46 | 1656 | 3 (0)| 00:00 |* 2 | INDEX RANGE SCAN | IND_A | 46 | | 2 (0)| 00:00 -------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_ID">=2000 AND "OBJECT_ID"<=2050) 14 rows selected