Understanding index

1,961 views

Published on

Understanding Oracle Btree index

Published in: Technology, Business
0 Comments
8 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,961
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
0
Comments
0
Likes
8
Embeds 0
No embeds

No notes for slide

Understanding index

  1. 1. Understanding BTree Index 主講人:申建忠
  2. 2. About mefrank_shen@uuu.com.tw 申建忠(Frank)
  3. 3. Agenda• What is INDEX?• BTree/Bitmap INDEX• Why Optimizer does not use my INDEX?• Constraint and INDEX• How to reorganize INDEX• TWO Myths about INDEX • PCTFREE limit • Reorganization is MUST
  4. 4. What are not include• Bitmap Index internal• Index-Organized Table• Partitioned Index• Function Based Index• Bitmap Join Index
  5. 5. What is INDEX• An index is an optional structure, associated with a table or table cluster, that can sometimes speed data access. By creating an index on one or more columns of a table, you gain the ability in some cases to retrieve a small set of randomly distributed rows from the table. Indexes are one of many means of reducing disk I/O. Oracle® Database Concepts 11g Release 2 (11.2) -3 Indexes and Index-Organized Tables
  6. 6. BTree Structure• BTree:Balanced Tree(B+Tree)• Balance: • The distance from root to any leaf node is always the same.• Height:The distance from root to leaf(max:24)• Difference between BTree and Bitmap Index • Index Entry Structure.• Branch: • Storage necessary information that can pointer to appropriate leaf.• Root:The top-level branch.• Leaf:Storage index entries.
  7. 7. BTree Structure Root Top-level branch Branch LevelHeight Branch Branch LeafIndex Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index EntryIndex Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index EntryIndex Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entry Index Entrysmallest biggest
  8. 8. Index Entry• BTree Index • [Header|Key Values|Rowid] • Each non-NULL key value has one index entry• Bitmap Index • [Header|Key Values|Start Rowid|End Rowid|Bitmap Segment] • Each distinct key value has one index entry,even NULL
  9. 9. SQL> CREATE TABLE frank.t1 (a NUMBER,b NUMBER,c Date); BTree Non-Unique IndexSQL> CREATE INDEX frank.t1_btree_idx ON hr.t1(a); Bitmap Non-Unique IndexSQL> CREATE BITMAP INDEX frank.t1_bitmap_idx ON hr.t1(b);SQL> INSERT INTO frank.t1 VALUES(1,1,SYSDATE);SQL> INSERT INTO frank.t1 VALUES(2,2,SYSDATE);SQL> INSERT INTO frank.t1 VALUES(1,1,SYSDATE);SQL> COMMIT;
  10. 10. SQL> SELECT object_name,object_id FROM dba_objects WHERE object_type=‘INDEX’ AND owner=‘FRANK’ AND object_name IN (T1_BTREE_IDX’,‘T1_BITMAP_IDX’); OBJECT_NAME OBJECT_ID------------------------------ ----------------T1_BTREE_IDX 76878T1_BITMAP_IDX 76879 Display Index BTree StructureSQL> ALTER SESSION SET EVENTS ‘IMMEDIATE TRACE NAME TREEDUMP LEVEL 76878’;leaf: 0x1000253 16777811 (0: nrow: 3 rrow: 3) --BTree IndexSQL> ALTER SESSION SET EVENTS ‘IMMEDIATE TRACE NAME TREEDUMP LEVEL 76879’;leaf: 0x100025b 16777819 (0: nrow: 2 rrow: 2) --Bitmap Index
  11. 11. Where is my Trace file?SQL> SHOW PARAMETER user_dump_destNAME TYPE VALUE---------------------- ------- -----------------------------------------------------user_dump_dest string /u01/app/oracle/diag/rdbms/orcl/orcl/traceSQL> SELECT spid FROM v$process WHERE addr=(SELECT paddr FROM v$session WHERE sid=(SELECT sid FROM v$mystat WHERE rownum<=1)); SPID---------- 3565--user tracefile named format : {SID}_ora_{ProcessID}.trc/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_3565.trc
  12. 12. SQL> CREATE OR REPLACE FUNCTION get_block_address(p_dba NUMBER) RETURN VARCHAR2 2 IS 3 v_file NUMBER; Convert Data Block Addrss(Decimal) 4 v_block NUMBER; to File number and Block number 5 BEGIN 6 v_file := DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(p_dba); 7 v_block := DBMS_UTILITY.DATA_BLOCK_ADDRESS_ BLOCK(p_dba); 8 RETURN file: ||v_file||,||block: ||v_block; 9 END; 10 /Function created.SQL> SELECT get_block_address(25166340) FROM dual;GET_BLOCK_ADDRESS(25166340)-------------------------------------------------------------------------------- Force DBWR write downfile: 6,block: 516 Dirty buffers to datafile Dump index block contentSQL> ALTER SYSTEM CHECKPOINT;SQL> ALTER SYSTEM DUMP DATAFILE 6 BLOCK 516;
  13. 13. BTree Index Dump col 0 col 1 Header Key Value Rowidrow#0[8020] flag: ------, lock: 2, len=12 Headercol 0; len 2; (2): c1 02 Key Value : 1col 1; len 6; (6): 01 00 02 4f 00 00 Rowidrow#1[7996] flag: ------, lock: 2, len=12 Headercol 0; len 2; (2): c1 02 Key Value : 1col 1; len 6; (6): 01 00 02 4f 00 02 Rowidrow#2[8008] flag: ------, lock: 2, len=12 Headercol 0; len 2; (2): c1 03 Key Value : 2col 1; len 6; (6): 01 00 02 4f 00 01 Rowid
  14. 14. Bitmap Index Dump col 0 col 1 col 2 col 3 Header Key Value Start Rowid End Rowid Bitmap Segsrow#0[8010] flag: ------, lock: 0, len=22 Headercol 0; len 2; (2): c1 02 Key Value : 1col 1; len 6; (6): 01 00 02 4f 00 00 Start Rowidcol 2; len 6; (6): 01 00 02 4f 00 07 End Rowidcol 3; len 2; (2): c8 05 Encoded Bitmap Segmentrow#1[7989] flag: ------, lock: 0, len=21col 0; len 2; (2): c1 03 Key Value : 2col 1; len 6; (6): 01 00 02 4f 00 00col 2; len 6; (6): 01 00 02 4f 00 07col 3; len 1; (1): 01
  15. 15. DML on TABLE• Manual DML on TABLE • Automatic maintenance on INDEX• INSERT on TABLE • INSERT on INDEX• DELETE on TABLE • DELETE on INDEX• UPDATE indexed column value on TABLE • DELETE then INSERT on INDEX
  16. 16. INSERT rows(BTree)SQL> CREATE TABLE frank.t2 (a NUMBER,b CHAR(200),c DATE);SQL> CREATE INDEX frank.t2_idx ON frank.t2(a); leaf: 0x1800204 25166340 (0: nrow: 0 rrow: 0) leaf(root) 1.empty leaf block 2.only leaf block,no branch need
  17. 17. Insert first rowSQL> insert into frank.t2 values(1,1,sysdate);leaf: 0x1800204 25166340 (0: nrow: 1 rrow: 1) leaf(root) 1 AAASxDAAEAAAAIPAAA
  18. 18. Insert another rowsSQL> insert into frank.t2 values(2,2,sysdate);leaf: 0x1800204 25166340 (0: nrow: 2 rrow: 2) leaf(root) 2 AAASxDAAEAAAAIPAAB 1 AAASxDAAEAAAAIPAAA
  19. 19. Leaf block fullSQL> insert into frank.t2 values(3,3,sysdate);SQL> insert into frank.t2 values(4,4,sysdate); leaf block full leaf(25166340) 4 AAASxDAAEAAAAIPAAD 3 AAASxDAAEAAAAIPAAC 2 AAASxDAAEAAAAIPAAB 1 AAASxDAAEAAAAIPAAA
  20. 20. Index Growing - 1branch: 0x1800204 25166340 (0: nrow: 2, level: 1) leaf: 0x1800218 25166360 (-1: nrow: 3 rrow: 3) leaf: 0x1800207 25166343 (0: nrow: 1 rrow: 1) Root block is always branch(25166340) on the same block kbx Height:2 brlmc 4 BLevel:1 add new leaf blocks 3 AAASxDAAEAAAAIPAAC 2 AAASxDAAEAAAAIPAAB 1 AAASxDAAEAAAAIPAAA 4 AAASxDAAEAAAAIPAAD leaf(25166360) leaf(25166343)
  21. 21. Continue InsertSQL> insert into frank.t2 values(5,5,sysdate);SQL> insert into frank.t2 values(6,6,sysdate);SQL> insert into frank.t2 values(7,7,sysdate);SQL> insert into frank.t2 values(8,8,sysdate); root(25166340) kbx brlmc 4 7 add new leaf block and leaf node splits 3 AAASxDAAEAAAAIPAAC 6 AAASxDAAEAAAAIPAAF 2 AAASxDAAEAAAAIPAAB 5 AAASxDAAEAAAAIPAAE 8 AAASxDAAEAAAAIPAAH 1 AAASxDAAEAAAAIPAAA 4 AAASxDAAEAAAAIPAAD 7 AAASxDAAEAAAAIPAAG leaf(25166360) leaf(25166355) leaf(25166343)
  22. 22. Index Growing - 2SQL> insert into frank.t2 values(9,9,sysdate);SQL> insert into frank.t2 values(10,10,sysdate); root(25166340) kbx Root and leaf brlmc 4 7 are both full 10 AAASxDAAEAAAAIPAAJ 3 AAASxDAAEAAAAIPAAC 6 AAASxDAAEAAAAIPAAF 9 AAASxDAAEAAAAIPAAI 2 AAASxDAAEAAAAIPAAB 5 AAASxDAAEAAAAIPAAE 8 AAASxDAAEAAAAIPAAH 1 AAASxDAAEAAAAIPAAA 4 AAASxDAAEAAAAIPAAD 7 AAASxDAAEAAAAIPAAG leaf(25166360) leaf(25166355) leaf(25166343)
  23. 23. Index Growing - 3 root(25166340) kbx Height:3 brlmc 7 BLevel:2 add new branch blocks kbx kbx brlmc 4 brlmc 10 branch(25166344) branch(25166345)3 AAASxDAAEAAAAIPAAC 6 AAASxDAAEAAAAIPAAF 9 AAASxDAAEAAAAIPAAI2 AAASxDAAEAAAAIPAAB 5 AAASxDAAEAAAAIPAAE 8 AAASxDAAEAAAAIPAAH1 AAASxDAAEAAAAIPAAA 4 AAASxDAAEAAAAIPAAD 7 AAASxDAAEAAAAIPAAG 10 AAASxDAAEAAAAIPAAJ leaf(25166360) leaf(25166355) leaf(25166343) leaf(25166356) leaf block split
  24. 24. Leaf Node SplitsSQL> SELECT m.*,s.name FROM v$mystat m,v$statname s WHERE m.statistic#=s.statistic# AND s.name LIKE %leaf%; SID STATISTIC# VALUE NAME---------- ---------------- ----------- -------------------------- 1 412 0 leaf node splits 1 413 0 leaf node 90-10 splits
  25. 25. root 1 Rowid 11 Rowid 3 Rowid 13 Rowid 21 Rowid 5 Rowid 15 Rowid 7 Rowid 17 Rowid 21 Rowid root 90-10 split1 Rowid 11 Rowid root3 Rowid 13 Rowid5 Rowid 15 Rowid7 Rowid 17 Rowid 1 Rowid 3 Rowid 12 Rowid 12 Rowid 5 Rowid 11 Rowid 15 Rowid 7 Rowid 13 Rowid 17 Rowid 50-50 split
  26. 26. DELETE rows SQL> DELETE frank.t2 WHERE a=5; root(25166340) kbx brlmc 7 kbx kbx brlmc 4 brlmc 10 branch(25166344) branch(25166345)3 AAASxDAAEAAAAIPAAC 6 AAASxDAAEAAAAIPAAF 9 AAASxDAAEAAAAIPAAI2 AAASxDAAEAAAAIPAAB 5 AAASxDAAEAAAAIPAAE 8 AAASxDAAEAAAAIPAAH1 AAASxDAAEAAAAIPAAA 4 AAASxDAAEAAAAIPAAD 7 AAASxDAAEAAAAIPAAG 10 AAASxDAAEAAAAIPAAJ
  27. 27. UPDATE indexed columns SQL> UPDATE frank.t2 SET a=11 WHERE a=1; root(25166340) kbx brlmc 7 kbx kbx brlmc 4 brlmc 10 branch(25166344) branch(25166345)3 AAASxDAAEAAAAIPAAC 6 AAASxDAAEAAAAIPAAF 9 AAASxDAAEAAAAIPAAI 2.insert new entry2 AAASxDAAEAAAAIPAAB 5 AAASxDAAEAAAAIPAAE 8 AAASxDAAEAAAAIPAAH 11 AAASxDAAEAAAAIPAAA1 AAASxDAAEAAAAIPAAA 4 AAASxDAAEAAAAIPAAD 7 AAASxDAAEAAAAIPAAG 10 AAASxDAAEAAAAIPAAJ1.delete old entry
  28. 28. Why Optimizer don’t use my index ?• just COST• Index unusable• index invisible• Index unavailable
  29. 29. Optimizer CostAccording to the CPU costing model:Cost = ( #SRds * sreadtim + #MRds * mreadtim + #CPUCycles / cpuspeed ) / sreadtimwhere: • #SRDs is the number of single block reads • #MRDs is the number of multi block reads • #CPUCycles is the number of CPU Cycles *) • sreadtim is the single block read time • mreadtim is the multi block read time • cpuspeed is the CPU cycles per secondCPUCycles includes CPU cost of query processing (pure CPU cost) and CPU cost ofdata retrieval (CPU cost of the buffer cache get).This model is straightforward for serial execution. Oracle9i Database Performance Tuning Guide and Reference Release 2 (9.2) - 9 Using EXPLAIN PLAN
  30. 30. SQL> CREATE TBALE frank.t3 AS SELECT LEVEL a,’b’||LEVEL b,SYSDATE c FROM dual CONNECT BY LEVEL<=500000;SQL> CREATE INDEX frank.t3_a_idx ON frank.t3(a);SQL> EXECUTE dbms_stats.gather_table_stats(‘FRANK’,’T3’);SQL> SELECT COUNT(*) FROM frank.t3; COUNT(*)----------------- 500000SQL> SELECT num_rows,num_blocks 2 FROM dba_tables 3 WHERE owner=‘FRANK’ AND table_name=’T3’; NUM_ROWS NUM_BLOCKS-------------------- -------------------- 500000 1820
  31. 31. index scan root branch branch1 rowid 4 rowid 7 rowid 10 rowid 13 rowid 16 rowid 19 rowid 22 rowid2 rowid 5 rowid 8 rowid 11 rowid 14 rowid 17 rowid 20 rowid 23 rowid3 rowid 6 rowid 9 rowid 12 rowid 15 rowid 18 rowid 21 rowid 24 rowid 1 a 4 d 7 g 10 j 2 b 5 e 8 h 11 kfull table scan 3 c 6 f 9 i 12 l 13 m 16 p 19 s 22 v 14 n 17 q 20 t 23 w 15 o 18 r 21 u 24 x
  32. 32. SQL> ALTER SESSION SET EVENTS ‘10053 TRACE NAME CONTEXT FOREVER,LEVEL 8’;SQL> SELECT a,b,c FROM frank.t3 WHERE a=1;1 rows selected.---------------------------------------------------------------------+----------------------------------------+| Id | Operation | Name | Rows | Bytes | Cost | Time |---------------------------------------------------------------------+----------------------------------------+| 0 | SELECT STATEMENT | | | | 4| || 1 | TABLE ACCESS BY INDEX ROWID | T3 | 1 | 21 | 4 | 00:00:01|| 2 | INDEX RANGE SCAN | T3_A_IDX| 1 | | 3 | 00:00:01|----------------------------------------------------------------------+----------------------------------------+Predicate Information:-----------------------------2 - access("A"=1)
  33. 33. SINGLE TABLE ACCESS PATH Single Table Cardinality Estimation for T3[T3] Column (#1): A( AvgLen: 5 NDV: 500000 Nulls: 0 Density: 0.000002 Min: 1 Max: 500000 Table: T3 Alias: T3 Card: Original: 500000.000000 Rounded: 1 Computed: 1.00 Non Adjusted: 1.00 Access Path: TableScan Cost: 500.47 Resp: 500.47 Degree: 0 Cost_io: 495.00 Cost_cpu: 112961061 Resp_io: 495.00 Resp_cpu: 112961061 Access Path: index (AllEqRange) Index: T3_A_IDX resc_io: 4.00 resc_cpu: 28876 ix_sel: 0.000002 ix_sel_with_filters: 0.000002 Cost: 4.00 Resp: 4.00 Degree: 1 Best:: AccessPath: IndexRange Index: T3_A_IDX Cost: 4.00 Degree: 1 Resp: 4.00 Card: 1.00 Bytes: 0
  34. 34. SQL> ALTER SESSION SET EVENTS ‘10053 TRACE NAME CONTEXT FOREVER,LEVEL 8’;SQL> SELECT a,b,c FROM frank.t3 WHERE a>1;499999 rows selected.--------------------------------------------------+-----------------------------------------+| Id | Operation | Name | Rows | Bytes | Cost | Time |--------------------------------------------------+-----------------------------------------+| 0 | SELECT STATEMENT | | | | 501 | || 1 | TABLE ACCESS FULL | T3 | 488K | 10M | 501 | 00:00:07 |--------------------------------------------------+------------------------------------------+Predicate Information:----------------------1 - filter("A">1)
  35. 35. SINGLE TABLE ACCESS PATH Single Table Cardinality Estimation for T3[T3] Column (#1): A( AvgLen: 5 NDV: 500000 Nulls: 0 Density: 0.000002 Min: 1 Max: 500000 Table: T3 Alias: T3 Card: Original: 500000.000000 Rounded: 499999 Computed: 499999.00 NonAdjusted: 499999.00 Access Path: TableScan Cost: 501.44 Resp: 501.44 Degree: 0 Cost_io: 495.00 Cost_cpu: 132960981 Resp_io: 495.00 Resp_cpu: 132960981 Access Path: index (RangeScan) Index: T3_A_IDX resc_io: 2897.00 resc_cpu: 215630422 ix_sel: 0.999998 ix_sel_with_filters: 0.999998 Cost: 2907.45 Resp: 2907.45 Degree: 1 Best:: AccessPath: TableScan Cost: 501.44 Degree: 1 Resp: 501.44 Card: 499999.00 Bytes: 0
  36. 36. SQL> ALTER SESSION SET EVENTS ‘10053 TRACE NAME CONTEXT FOREVER,LEVEL 8’;SQL> SELECT a,b,c FROM frank.t3 WHERE a>490000;10000 rows selected.---------------------------------------------------------------------+----------------------------------------+| Id | Operation | Name | Rows | Bytes | Cost | Time |---------------------------------------------------------------------+----------------------------------------+| 0 | SELECT STATEMENT | | | | 61 | || 1 | TABLE ACCESS BY INDEX ROWID | T3 | 10K | 205K| 61 | 00:00:01|| 2 | INDEX RANGE SCAN | T3_A_IDX| 10K | | 25 | 00:00:01|----------------------------------------------------------------------+----------------------------------------+Predicate Information:-----------------------------2 - access("A">490000)
  37. 37. SINGLE TABLE ACCESS PATH Single Table Cardinality Estimation for T3[T3] Column (#1): A( AvgLen: 5 NDV: 500000 Nulls: 0 Density: 0.000002 Min: 1 Max: 500000 Table: T3 Alias: T3 Card: Original: 500000.000000 Rounded: 10000 Computed: 10000.02 NonAdjusted: 10000.02 Access Path: TableScan Cost: 500.49 Resp: 500.49 Degree: 0 Cost_io: 495.00 Cost_cpu: 113361021 Resp_io: 495.00 Resp_cpu: 113361021 Access Path: index (RangeScan) Index: T3_A_IDX resc_io: 61.00 resc_cpu: 4334798 ix_sel: 0.020000 ix_sel_with_filters: 0.020000 Cost: 61.21 Resp: 61.21 Degree: 1 Best:: AccessPath: IndexRange Index: T3_A_IDX Cost: 61.21 Degree: 1 Resp: 61.21 Card: 10000.02 Bytes: 0
  38. 38. Index properties• Usability Indexes are usable (default) or unusable. An unusable index is not maintained by DML operations and is ignored by the optimizer. An unusable index can improve the performance of bulk loads. Instead of dropping an index and later re-creating it, you can make the index unusable and then rebuild it. Unusable indexes and index partitions do not consume space. When you make a usable index unusable, the database drops its index segment.• Visibility Indexes are visible (default) or invisible. An invisible index is maintained by DML operations and is not used by default by the optimizer. Making an index invisible is an alternative to making it unusable or dropping it. Invisible indexes are especially useful for testing the removal of an index before dropping it or using indexes temporarily without affecting the overall application. Oracle® Database Concepts 11g Release 2 (11.2) -3 Indexes and Index-Organized Tables
  39. 39. Unusable IndexSQL> SELECT status FROM dba_indexes WHERE owner=‘FRANK’ and table_name=’T3’;STATUS---------------UNUSABLESQL> SELECT a,b,c FROM frank.t3 WHERE a=1;1 rows selected.--------------------------------------------------+-----------------------------------------+| Id | Operation | Name | Rows | Bytes | Cost | Time |--------------------------------------------------+-----------------------------------------+| 0 | SELECT STATEMENT | | | | 500 | || 1 | TABLE ACCESS FULL | T3 | 1| 21 | 500 | 00:00:06 |--------------------------------------------------+-----------------------------------------+Predicate Information:----------------------1 - filter("A"=1)
  40. 40. Don’t skip unusable IndexSQL> SHOW PARAMETER skip_unusable_indexeNAME TYPE VALUE------------------------------------ ----------- ------------------------------skip_unusable_indexes boolean TRUESQL> ALTER SYSTEM SET skip_unusable_indexes=FALSE;Session altered.SQL> SELECT a,b,c FROM frank.t3 WHERE a=1;SELECT a,b,c FROM frank.t1 WHERE a=1;*ERROR at line 1:ORA-01502: index FRANK.T3_A_IDX or partition of such index isin unusable state
  41. 41. Invisible IndexSQL> ALTER INDEX frank.t3_a_idx INVISIBLE;SQL> SELECT status,visibility FROM dba_indexes 2 WHERE owner=FRANK AND table_name=T3;STATUS VISIBILIT----------- -------------VALID INVISIBLESQL> SELECT a,b,c FROM frank.t3 WHERE a=1;1 rows selected.--------------------------------------------------+-----------------------------------------+| Id | Operation | Name | Rows | Bytes | Cost | Time |--------------------------------------------------+-----------------------------------------+| 0 | SELECT STATEMENT | | | | 500 | || 1 | TABLE ACCESS FULL | T3 | 1| 21 | 500 | 00:00:06 |--------------------------------------------------+-----------------------------------------+Predicate Information:----------------------1 - filter("A"=1)
  42. 42. SQL> SHOW PARAMETER optimizer_use_invisible_indexesNAME TYPE VALUE------------------------------------------- ----------- ------------------------------optimizer_use_invisible_indexes boolean FLASESQL> ALTER SESSION SET optimizer_use_invisible_indexes=TRUE;SQL> SELECT a,b,c FROM frank.t3 WHERE a=1;1 rows selected.---------------------------------------------------------------------+----------------------------------------+| Id | Operation | Name | Rows | Bytes | Cost | Time |---------------------------------------------------------------------+----------------------------------------+| 0 | SELECT STATEMENT | | | | 4| || 1 | TABLE ACCESS BY INDEX ROWID| T3 | 1 | 21 | 4 | 00:00:01 || 2 | INDEX RANGE SCAN | T3_A_IDX| 1 | | 3 | 00:00:01 |----------------------------------------------------------------------+----------------------------------------+Predicate Information:-----------------------------2 - access("A"=1)SQL> ALTER INDEX frank.t3_a_idx VISIBLE;
  43. 43. Index unavailable• 條件式為IS NULL或IS NOT NULL或NOT • SELECT a,b,c FROM frank.t1 WHERE a IS NULL; • SELECT a,b,c FROM frank.t1 WHERE a != 1;• indexed column被包含在運算式或函數 • SELECT a,b,c FROM frank.t1 WHERE a+100=101; • SELECT a,b,c FROM frank.t1 WHERE TO_CHAR(a)=’1’;• LIKE條件式為’%xx’或’%xx%’ • SELECT a,b,c FROM frank.t1 WHERE b LIKE ‘%12’;
  44. 44. Implicit type conversionSQL> SELECT a,b,c FROM frank.t3 WHERE a = 100000; AB C------------- ----------------------------------------- ------------ 100000 b100000 07-FEB-12---------------------------------------------------------------------+----------------------------------------+| Id | Operation | Name | Rows | Bytes | Cost | Time |---------------------------------------------------------------------+----------------------------------------+| 0 | SELECT STATEMENT | | | | 61 | || 1 | TABLE ACCESS BY INDEX ROWID | T3 | 10K | 205K| 61 | 00:00:01|| 2 | INDEX RANGE SCAN | T3_A_IDX| 10K | | 25 | 00:00:01|----------------------------------------------------------------------+----------------------------------------+Predicate Information: Happy Ending-----------------------------2 - access("A"=100000)
  45. 45. Implicit type conversionSQL> SELECT a,b,c FROM frank.t3 WHERE a LIKE 100000; AB C------------- ----------------------------------------- ------------ 100000 b100000 07-FEB-12--------------------------------------------------+-----------------------------------------+| Id | Operation | Name | Rows | Bytes | Cost | Time |--------------------------------------------------+-----------------------------------------+| 0 | SELECT STATEMENT | | | | 500 | || 1 | TABLE ACCESS FULL | T3 | 1 | 21 | 500 | 00:00:06 |--------------------------------------------------+-----------------------------------------+Predicate Information: Bad Ending----------------------1 - filter(TO_CHAR(“A”)=‘100000’)
  46. 46. Index and Constraints• Primary Key and Unique Constraints • Index must exist • Improve integrity constraint check time• Foreign Key Constraints • suggest to create btree index on FK • Improve integrity constraint check time • Less Lock Contentions on Child Table • Prevent Dead Lock
  47. 47. Enable Primary Key/ Unique ConstraintEnable PK/UK Is index Yes Using existing existed on pk/uk Constraint index columns? NoCreate Unique No Is constraint Yes Create Non- Index deferrable? Unique Index
  48. 48. Default type:SQL> CREATE TABLE frank.t4 NOT DEFERRABLE (a NUMBER CONSTRAINT t4_a_pk PRIMARY KEY, b VARCHAR2(10) CONSTRAINT t4_b_uk UNIQUE DEFERRABLE);SQL> SELECT constraint_name,constraint_type,deferrable,index_name FROM dba_constraints WHERE owner=HR and table_name=T3;CONSTRAINT_NAME C DEFERRABLE INDEX_NAME------------------------------ - -------------------------- --------------------T4_B_UK U DEFERRABLE T4_B_UKT4_A_PK P NOT DEFERRABLE T4_A_PKSQL> SELECT index_name,index_type,uniqueness FROM dba_indexes WHERE owner=‘FRANK’ and table_name=’T4’;INDEX_NAME INDEX_TYPE UNIQUENES------------------------------ --------------------------- ------------------T4_A_PK NORMAL UNIQUET4_B_UK NORMAL NONUNIQUE
  49. 49. Disable/Drop Primary Key/Unique ConstraintDisable/Drop PK/UK Is Index Yes Is Index Yes Drop exising auto-created? uniqueness? Index Constraint No No Keep existing Keep existing Index Index
  50. 50. SQL> ALTER TABLE frank.t4 DROP CONSTRAINT t4_a_pk; --Drop PKSQL> ALTER TABLE frank.t4 DROP CONSTRAINT t4_b_uk; --Drop UKSQL> SELECT constraint_name,constraint_type,deferrable,index_name FROM dba_constraints WHERE owner=FRANK and table_name=T4;no rows selectedSQL> SELECT index_name,index_type,uniqueness FROM dba_indexes WHERE owner=‘FRANK’ and table_name=’T4’;INDEX_NAME INDEX_TYPE UNIQUENES------------------------------ --------------------------- ------------------T4_B_UK NORMAL NONUNIQUE After drop/disable PK/UK constraint, auto-created unique index will be dropped.
  51. 51. SQL> CREATE UNIQUE INDEX frank.t4_a_idx ON frank.t4(a); --Create indexSQL> ALTER TABLE frank.t4 ADD CONSTRAINT t4_a_pk PRIMARY KEY(a);SQL> SELECT constraint_name,constraint_type,deferrable,index_name FROM dba_constraints WHERE owner=FRANK and table_name=T4;CONSTRAINT_NAME DEFERRABLE C INDEX_NAME------------------------------ - -------------------------- --------------------T4_A_PK P NOT DEFERRABLE T4_A_IDX --PK use existing indexSQL> ALTER TABLE frank.t4 DROP CONSTRAINT t4_a_pk; --Drop PK constraintSQL> SELECT index_name,index_type,uniqueness FROM dba_indexes WHERE owner=‘FRANK’ and table_name=’T4’;INDEX_NAME INDEX_TYPE UNIQUENES Manual created------------------------------ --------------------------- ------------------ index would notT4_A_IDX NORMAL UNIQUE be autodroppedT4_B_UK NORMAL NONUNIQUE
  52. 52. No Index On FK cols INSERT DML DETELE UPDATE FK value 3.TX:X 2.TM:RX 1.TM:RX PK 1 a1Parent 1 a2 2 b 2 b1 1 a FK Child
  53. 53. Insert into Parent Table INSERT DML DETELE UPDATE FK value 3.TX:X INSERT 2.TM:RX 2.TM:RX 1.TM:RXPK 1 a13 c 1 a2 1.TM:RX2 b 2 b1 3.TX:X1 a FK
  54. 54. Update Parent Table INSERT DML DETELE UPDATE FK value 2.TM:RX UPDATE 2.TM:S(release after hold) 1.TM:RXPK 1 a13=>4 c 1 a2 1.TM:RX 2 b 2 b1 3.TX:X 1 a FK
  55. 55. Delete Parent Table - 1 INSERT DML DETELE UPDATE FK value 2.TM:RX DELETE 2.TM:S(release after hold) 1.TM:RXPK 1 a13 c 1 a2 1.TM:RX2 b 2 b1 3.TX:X1 a FK No Action
  56. 56. Delete Parent Table - 2 INSERT DML DETELE UPDATE FK value 2.TM:RX DELETE 2.TM:SRX -> RX 1.TM:RXPK 1 a13 c 1 a2 1.TM:RX2 b 2 b11 a FK On Delete Cascade
  57. 57. Delete Parent Table - 3 INSERT DML DETELE UPDATE FK value 3.TX:X DELETE 2.TM:RX 2.TM:RX 1.TM:RXPK 1 a13 c 1 a2 1.TM:RX2 b 2 b1 3.TX:X1 a FK On Delete Cascade
  58. 58. FK without IndexSQL> INSERT INTO child VALUES(2,’b2’);1 row created.SQL> DECLARE PRAGMA autonomous_transaction; BEGIN DELETE parent WHERE a=3; COMMIT; END;--after wait a short timeDECLARE*ERROR at line 1:ORA-00060: deadlock detected while waiting forresourceORA-06512: at line 4
  59. 59. Index On FK cols BTree index INSERT DML DETELE UPDATE FK value 3.TX:X 2.TM:RX 1.TM:RX PK 1 a1Parent 1 a2 2 b 2 b1 1 a FK Child
  60. 60. Insert into Parent Table - 10g BTree index INSERT DML DETELE UPDATE FK value 2.TX:X INSERT 2.TM:RS 1.TM:RX 1.TM:RXPK 1 a13 c 1 a2 1.TM:RX2 b 2 b1 3.TX:X1 a FK
  61. 61. Insert into Parent Table - 11g BTree index INSERT DML DETELE UPDATE FK value 2.TX:X INSERT 2.TM:RX 1.TM:RX 1.TM:RXPK 1 a13 c 1 a2 1.TM:RX2 b 2 b1 3.TX:X1 a FK
  62. 62. Update Parent Table - 10g BTree index INSERT DML DETELE UPDATE FK value 2.TX:X UPDATE 2.TM:RS 1.TM:RX 1.TM:RXPK 1 a13=>4 c 1 a2 1.TM:RX 2 b 2 b1 3.TX:X 1 a FK
  63. 63. Update Parent Table - 11g BTree index INSERT DML DETELE UPDATE FK value 2.TX:X UPDATE 2.TM:RX 1.TM:RX 1.TM:RXPK 1 a13=>4 c 1 a2 1.TM:RX 2 b 2 b1 3.TX:X 1 a FK
  64. 64. Delete Parent Table - 10g BTree index INSERT DML DETELE UPDATE FK value 2.TX:X DELETE 2.TM:RS 1.TM:RX 1.TM:RXPK 1 a13 c 1 a2 1.TM:RX2 b 2 b1 3.TX:X1 a FK
  65. 65. Delete Parent Table - 11g BTree index INSERT DML DETELE UPDATE FK value 2.TX:X DELETE 2.TM:RX 1.TM:RX 1.TM:RXPK 1 a13 c 1 a2 1.TM:RX2 b 2 b1 3.TX:X1 a FK
  66. 66. FK with IndexSQL> INSERT INTO child VALUES(2,’b2’);1 row created.SQL> DECLARE PRAGMA autonomous_transaction; BEGIN DELETE parent WHERE a=3; COMMIT; No more Deadlock END;PL/SQL procedure successfully completed.
  67. 67. Index Reorganization• ALTER INDEX index_name REBUILD;• ALTER INDEX index_name REBUILD ONLINE;• ALTER INDEX index_name COALESCE;• DROP INDEX then CREATE INDEX
  68. 68. Rebuild or Coalesce? Rebuild Index Coalesce IndexQuickly moves index to another tablespace Cannot move index to another tablespaceHigher cost: requires more disk space Lower costs: does not require more disk spaceCreates new tree,shrinks height if applicable Coalesce leaf blocks within same branch of treeEnables you to quickly change storage andtablespace parameters without having to drop the Quickly frees up index leaf blocks for useoriginal index Oracle® Database Administrators Guide 11g Release 2 (11.2) - 21 Managing Indexes
  69. 69. Rebuild Rebuild SQL> ALTER INDEX xxx REBUILD;DML TM:S
  70. 70. Rebuild online - 10g e lin on u ild R eb SQL> ALTER INDEX xxx REBUILD ONLINE;DML TM:S(release immediate)-Begin TM:RS TM:S(release immediate)-End
  71. 71. Rebuild online - 11g e lin on u ild R eb SQL> ALTER INDEX xxx REBUILD ONLINE;DML TX:S(ongoing transaction)-Begin TM:RS TX:S(ongoing transaction)-End
  72. 72. Height Coalesce Index SQL> ALTER INDEX xxx COALESCE; TM:RS DML
  73. 73. Index Related Myths• PCTFREE always take effect • pctfree only effect on creation• ReOrganization is MUST • Depends on deleted space can be reused or not
  74. 74. INDEX Before INSERTSQL> CREATE TABLE frank.t5 2 (a NUMBER,b CHAR(200),c DATE);SQL> CREATE INDEX frank.t5_ab_idx ON frank.t5(a,b) 2 PCTFREE 50 --default:10 3 TABLESPACE ts2k;SQL> INSERT INTO frank.t5 2 SELECT LEVEL,b||LEVEL,SYSDATE+LEVEL 3 FROM dual CONNECT BY LEVEL<=8;SQL> COMMIT;SQL> ANALYZE INDEX frank.t5_ab_idx VALIDATE STRUCTURE;SQL> SELECT lf_rows,lf_blks,del_lf_rows,used_space,pct_used FROM index_stats; LF_ROWS LF_BLKS DEL_LF_ROWS USED_SPACE PCT_USED---------------- -------------- -------------------- ------------------- ---------------- 8 1 0 1728 94
  75. 75. INDEX After INSERTSQL> CREATE TABLE frank.t6 AS SELECT * FROM frank.t5;SQL> CREATE INDEX frank.t6_ab_idx ON frank.t6(a,b) 2 PCTFREE 50 3 TABLESPACE ts2k;SQL> ANALYZE INDEX frank.t6_ab_idx VALIDATE STRUCTURE;SQL> SELECT lf_rows,lf_blks,del_lf_rows,used_space,pct_used FROM index_stats; LF_ROWS LF_BLKS DEL_LF_ROWS USED_SPACE PCT_USED---------------- -------------- -------------------- ------------------- ---------------- 8 3 0 1748 24branch: 0x1800224 25166372 (0: nrow: 3, level: 1) --TREEDUMP leaf: 0x1800225 25166373 (-1: nrow: 3 rrow: 3) leaf: 0x1800226 25166374 (0: nrow: 3 rrow: 3) leaf: 0x1800227 25166375 (1: nrow: 2 rrow: 2)
  76. 76. INDEX maintenance ignore PCTFEE settingSQL> INSERT INTO frank.t6 VALUES(9,’b9’,SYSDATE);SQL> INSERT INTO frank.t6 VALUES(10,‘b10’,SYSDATE);SQL> INSERT INTO frank.t6 VALUES(11,‘b11’,SYSDATE); Index EntriesSQL> INSERT INTO frank.t6 VALUES(12,‘b12’,SYSDATE);SQL> INSERT INTO frank.t6 VALUES(13,‘b13’,SYSDATE);SQL> INSERT INTO frank.t6 VALUES(14,‘b14’,SYSDATE);SQL> COMMIT;branch: 0x1800224 25166372 (0: nrow: 3, level: 1) leaf: 0x1800225 25166373 (-1: nrow: 3 rrow: 3) leaf: 0x1800226 25166374 (0: nrow: 3 rrow: 3) leaf: 0x1800227 25166375 (1: nrow: 8 rrow: 8)
  77. 77. SQL> CREATE TABLE frank.t7 2 (a NUMBER,b CHAR(200),c DATE);SQL> CREATE INDEX frank.t7_ab_idx ON frank.t7(a,b) TABLESPACE ts2k;SQL> INSERT INTO frank.t7 2 SELECT LEVEL,b||LEVEL,SYSDATE+LEVEL 3 FROM dual CONNECT BY LEVEL<=20;SQL> COMMIT;SQL> ANALYZE INDEX frank.t7_ab_idx VALIDATE STRUCTURE;SQL> SELECT lf_rows,lf_blks,del_lf_rows,used_space,pct_used FROM index_stats; LF_ROWS LF_BLKS DEL_LF_ROWS USED_SPACE PCT_USED---------------- -------------- -------------------- ------------------ ----------------- 20 3 0 4340 59branch: 0x1800244 25166404 (0: nrow: 3, level: 1) leaf: 0x1800254 25166420 (-1: nrow: 8 rrow: 8) leaf: 0x180024e 25166414 (0: nrow: 8 rrow: 8) leaf: 0x180024f 25166415 (1: nrow: 4 rrow: 4)
  78. 78. INDEX just be created 25166404 root1,b1 Rowid 9,b9 Rowid2,b2 Rowid 10,b10 Rowid3,b3 Rowid 11,b11 Rowid4,b4 Rowid 12,b12 Rowid5,b5 Rowid 13,b13 Rowid 17,b17 Rowid6,b6 Rowid 14,b14 Rowid 18,b18 Rowid7,b7 Rowid 15,b15 Rowid 19,b19 Rowid8,b8 Rowid 16,b16 Rowid 20,b20 Rowid 25166420 25166414 25166415
  79. 79. SQL> DELETE frank.t7 WHERE MOD(a,2)=0;10 rows deleted.SQL> COMMIT;SQL> ANALYZE INDEX frank.t7_ab_idx VALIDATE STRUCTURE;SQL> SELECT lf_rows,lf_blks,del_lf_rows,used_space,pct_used FROM index_stats; LF_ROWS LF_BLKS DEL_LF_ROWS USED_SPACE PCT_USED---------------- -------------- -------------------- ------------------ ----------------- 20 3 10 4340 59 del_lf_rows/lf_rows=50% If > 20% then reorganized index Really need to do this ?branch: 0x1800244 25166404 (0: nrow: 3, level: 1) leaf: 0x1800254 25166420 (-1: nrow: 8 rrow: 4) leaf: 0x180024e 25166414 (0: nrow: 8 rrow: 4) leaf: 0x180024f 25166415 (1: nrow: 4 rrow: 2)
  80. 80. INDEX after Delete 25166404 root1,b1 Rowid 9,b9 Rowid2,b2 Rowid 10,b10 Rowid3,b3 Rowid 11,b11 Rowid4,b4 Rowid 12,b12 Rowid5,b5 Rowid 13,b13 Rowid 17,b17 Rowid6,b6 Rowid 14,b14 Rowid 18,b18 Rowid7,b7 Rowid 15,b15 Rowid 19,b19 Rowid8,b8 Rowid 16,b16 Rowid 20,b20 Rowid 25166420 25166414 25166415
  81. 81. SQL> INSERT INTO frank.t7 VALUES(2,’b2’,SYSDATE);SQL> INSERT INTO frank.t7 VALUES(4,’b4’,SYSDATE); index entriesSQL> INSERT INTO frank.t7 VALUES(6,’b6’,SYSDATE);SQL> INSERT INTO frank.t7 VALUES(8,’b8’,SYSDATE);SQL> COMMIT;SQL> ANALYZE INDEX frank.t7_ab_idx VALIDATE STRUCTURE;SQL> SELECT lf_rows,lf_blks,del_lf_rows,used_space,pct_used 2 FROM index_stats; LF_ROWS LF_BLKS DEL_LF_ROWS USED_SPACE PCT_USED---------------- -------------- -------------------- ------------------ ----------------- 20 3 6 4340 59branch: 0x1800244 25166404 (0: nrow: 3, level: 1) leaf: 0x1800254 25166420 (-1: nrow: 8 rrow: 8) leaf: 0x180024e 25166414 (0: nrow: 8 rrow: 4) leaf: 0x180024f 25166415 (1: nrow: 4 rrow: 2)
  82. 82. Reuse deleted space 25166404 rootReuse deleted spaceReorganization is not necessary1,b1 Rowid 9,b9 Rowid2,b2 Rowid 10,b10 Rowid3,b3 Rowid 11,b11 Rowid4,b4 Rowid 12,b12 Rowid5,b5 Rowid 13,b13 Rowid 17,b17 Rowid6,b6 Rowid 14,b14 Rowid 18,b18 Rowid7,b7 Rowid 15,b15 Rowid 19,b19 Rowid8,b8 Rowid 16,b16 Rowid 20,b20 Rowid 25166420 25166414 25166415
  83. 83. SQL> INSERT INTO frank.t7 VALUES(21,‘b21’,SYSDATE);SQL> INSERT INTO frank.t7 VALUES(31,‘b31’,SYSDATE); index entriesSQL> INSERT INTO frank.t7 VALUES(41,‘b41’,SYSDATE);SQL> INSERT INTO frank.t7 VALUES(51,‘b51’,SYSDATE);SQL> COMMIT;SQL> ANALYZE INDEX frank.t7_ab_idx VALIDATE STRUCTURE;SQL> SELECT lf_rows,lf_blks,del_lf_rows,used_space,pct_used 2 FROM index_stats; LF_ROWS LF_BLKS DEL_LF_ROWS USED_SPACE PCT_USED---------------- -------------- -------------------- ------------------ ----------------- 22 3 8 4772 65branch: 0x1800244 25166404 (0: nrow: 3, level: 1) leaf: 0x1800254 25166420 (-1: nrow: 8 rrow: 4) leaf: 0x180024e 25166414 (0: nrow: 8 rrow: 4) leaf: 0x180024f 25166415 (1: nrow: 6 rrow: 6)
  84. 84. Can’t reuse deleted space 25166404 rootDeleted space does not be reusedReorganization is necessary1,b1 Rowid 9,b9 Rowid2,b2 Rowid 10,b10 Rowid3,b3 Rowid 11,b11 Rowid 51,b51 Rowid4,b4 Rowid 12,b12 Rowid 41,b41 Rowid5,b5 Rowid 13,b13 Rowid 17,b17 Rowid6,b6 Rowid 14,b14 Rowid 31,b31 Rowid7,b7 Rowid 15,b15 Rowid 19,b19 Rowid8,b8 Rowid 16,b16 Rowid 21,b21 Rowid 25166420 25166414 25166415
  85. 85. Q&A• Http://www.uuu.com.tw• Email:frank_shen@uuu.com.tw• Blog://frankshenoracle.blogspot.com

×