Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

1,041 views
881 views

Published on

There's more to indexing than the basic "create index" statement! We'll go under the covers and look at the different types of indexes available in both Enterprise and Standard Editions, including b-tree, bitmap, reverse-key, functional, composite and partitioned; describe how to select the most appropriate type of index for a particular situation; explore storage parameters and lesser-known configuration options available to fine-tune performance; discuss methods for gathering statistics, including whether to capture histograms or not; and cover techniques for managing and maintaining a healthy library of indexes. Scripts included!

1. How to choose the appropriate type of index for a particular implementation.
2. An understanding of indexing options and storage configurations available to improve index (and database) performance.
3. Techniques for managing and maintaining the health of indexes.

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

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

No notes for slide

Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

  1. 1. INDEXING STRATEGIES Sean Scott Oracle DBA, Bodybuilding.com
  2. 2. “An index is an optional structure, associated with a table or table cluster, that can sometimes speed data access.”
  3. 3. B-TREE INDEXES • Most common type of index • Data is ordered within the index • Consists of branches and leaves
  4. 4. B-TREE INDEXES
  5. 5. B-TREE INDEXES • Options include • Unique • Descending • Reverse Key • Index Organized Tables • Composite, Covering, Concatenated • Compressed
  6. 6. REVERSE KEY INDEXES • Creates a “mirror image” of the key • UTOUG would become GUOTU • Used to spread block splits and avoid hot blocks in RAC environments • No index range scans • Lots of conflicting information • Test extensively, and use with caution
  7. 7. REVERSE KEY INDEXES • Two implementations: • last_updated_date in a customer order table • Sequentially updated primary key
  8. 8. REVERSE KEY INDEXES • Things to watch for: • Increase in db sequential read wait events • Backup time increase • Space use increase
  9. 9. INDEX ORGANIZED TABLES • Stores data and index in the same segment • Must have a primary key • Data is ordered • Can have secondary indexes • Useful for tables that are fully accessed • Overflow for less-used data
  10. 10. COMPOSITE INDEXES • Sometimes known as covering or concatenated • Consist of more than one column • Leading column is important
  11. 11. COMPOSITE INDEXES create index test_i1 on test(col1); create index test_i2 on test(col1, col2);
  12. 12. COMPOSITE INDEXES • Choosing a leading column • High cardinality? • Low cardinality? • Most frequently accessed
  13. 13. • The Poor-Man’s IOT • Use to improve performance of select by reducing I/O COVERING INDEXES
  14. 14.  SELECT price_id ,         price       FROM dcs_price     WHERE version_id       = :1       AND price_id           = :2; ------------------------------------------------------------------------------------------- | Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     | ------------------------------------------------------------------------------------------- |   0 | SELECT STATEMENT            |             |     1 |    29 |     5   (0)| 00:00:01 | |*  1 |  TABLE ACCESS BY INDEX ROWID| DCS_PRICE   |     1 |    29 |     5   (0)| 00:00:01 | |*  2 |   INDEX RANGE SCAN          | DCS_PRICE_P |     2 |       |     3   (0)| 00:00:01 | -------------------------------------------------------------------------------------------
  15. 15. create unique index dcs_price_i3       on dcs_price ( price_id , version_id , price); ----------------------------------------------------------------------------------- | Id  | Operation        | Name           | Rows  | Bytes | Cost (%CPU)| Time     | ----------------------------------------------------------------------------------- |   0 | SELECT STATEMENT |                |     1 |    22 |     2   (0)| 00:00:01 | |*  1 |  INDEX RANGE SCAN| DCS_PRICE_I03 |     1 |    22 |     2   (0)| 00:00:01 | -----------------------------------------------------------------------------------
  16. 16. COMPRESSED KEY INDEXES • Leading columns have low cardinality • Save space • Improve performance
  17. 17. BITMAP INDEXES • Index on low cardinality data • Take up little space • Bitmap join • Typically found in data warehouse environments
  18. 18. FUNCTION BASED, INDEXEDVIRTUAL • Index on a database function (predefined, user written) • Allows index lookups when a function is used • Both store the derived value in the index
  19. 19. INVISIBLE INDEXES • Create or modify an index to be invisible • Invisible to the optimizer • Still maintained by the database • Better, more reliable option than MONITORING USAGE • Must set optimizer_use_invisible_indexes=TRUE
  20. 20. VIRTUAL INDEXES • Only visible to the optimizer • Used for evaluating an indexes usefulness
  21. 21. VIRTUAL INDEXES SQL> create table test (col1 integer); Table created. SQL> create index test_i1 on test(col1); Index created. SQL> create index test_i2 on test(col1); create index test_i2 on test(col1) * ERROR at line 1: ORA-01408: such column list already indexed
  22. 22. VIRTUAL INDEXES SQL> create index test_i2 on test(col1) nosegment; Index created. SQL> select table_name, index_name, column_name from user_ind_columns where table_name = 'TEST'; TABLE_NAME INDEX_NAME COLUMN_NAME ------------------------------ ------------------------------ -------------------- TEST TEST_I1 COL1 TEST TEST_I2 COL1
  23. 23. CLUSTER INDEXES • B-Tree Cluster Index • Hash Cluster Index • Hash clusters can exist on a single table
  24. 24. PARTITIONED INDEXES • Global Partitioned • Crosses partitions • Exists on whole table • Local Partitioned • Unique to each partition • Watch out for non-partitioned indexes on partitions
  25. 25. PARTITIONED INDEXES • Locally partitioned indexes • Isolate maintenance operations to a single partition • Mark unusable/invisible independently • Separate partitions into different tablespaces • Prefixed, non-prefixed • Unique indexes must include partition key • Can only exist on partitioned tables
  26. 26. PARTITIONED INDEXES • Globally partitioned indexes • Can exist on non-partitioned tables • Can be either range or hash based • Partition maintenance can render the index unusable • Global indexes on partitioned tables must lead with the partition key
  27. 27. PARTITIONED INDEXES Local partition Partition index unusable Partition index unusable Partitions involved unusable Partition index unusable No effect on index No effect on index Global or non-partition Entire index unusable Entire index unusable Entire index unusable Entire index unusable Entire index unusable Entire index unusable Operation Split Move Merge Exchange Truncate Drop
  28. 28. WHAT TO INDEX • Primary keys • Unique keys • Foreign keys • Columns frequently used in where, distinct, and order by clauses • Columns often queried together
  29. 29. Index all that should be, and no more.
  30. 30. If in doubt, b-tree is probably safest.
  31. 31. KEY CONSIDERATIONS Create primary and unique keys within a create table or build the indexes and constraints separately? The create table method is easier, but: • Indexes don’t persist • May break GoldenGate, replication
  32. 32. create table test1 ( col1 integer); create unique index test1_p on test1(col1); alter table test1 add constraint test1_p primary key (col1) using index test1_p; create table test2 ( col1 integer primary key); -or- create table test2 ( col1 integer, constraint test2_p primary key (col1));
  33. 33. select table_name, index_name from dba_indexes where table_name like 'TEST%'; TEST2 SYS_C0015135 TEST1 TEST1_P
  34. 34. alter table test1 drop constraint test1_p; alter table test2 drop constraint SYS_C0015135; select table_name, index_name from dba_indexes where table_name like 'TEST%'; TEST1 TEST1_P
  35. 35. • Pick a convention and stick to it! • tablename_p • tablename_un • tablename_in • tablename_fn • tablename_bn • ...etc NAMING CONVENTION
  36. 36. -------------------------------------------------------------------------------------------------------- | Id | Operation" " " "" " " | Name" " " | Rows | Bytes| Cost (%CPU)| Time " | -------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT"" "" " " |" " " " | 30| 4230| 560 (1)| 00:00:07| | 1 | SORT ORDER BY" " " "" " |" " " " | 30| 4230| 560 (1)| 00:00:07| | 2 | NESTED LOOPS" " " "" " |" " " " | 30| 4230| 559 (1)| 00:00:07| | 3 | NESTED LOOPS "" "" " " |" " " " | 30| 3630| 552 (1)| 00:00:07| | 4 | NESTED LOOPS"" "" " " |" " " " | 30| 2790| 544 (1)| 00:00:07| | 5 | MERGE JOIN "" "" " " |" " " " | 30| 1290| 537 (1)| 00:00:07| |* 6 | TABLE ACCESS BY INDEX ROWID " | TICKET_STATUSES" | 7| 42| 1 (0)| 00:00:01| |* 7 | INDEX FULL SCAN" " "" | SYS_C0107546 | 10| | 1 (0)| 00:00:01| |* 8 | SORT JOIN "" "" " " |" " " " | 35| 1295| 536 (1)| 00:00:07| |* 9 | TABLE ACCESS BY INDEX ROWID " | TICKETS"" " | 35| 1295| 535 (1)| 00:00:07| | 10 | " BITMAP CONVERSION TO ROWIDS " " |" " " " | | |" " |" " | | 11 | " BITMAP AND" " "" " " |" " " " | | |" " " |" " | | 12 | " BITMAP MINUS" " "" " |" " " " | | |" " | " " | |* 13 | " BITMAP INDEX SINGLE VALUE" " | TICKETS1 " | | |" " | " " | |* 14 | " BITMAP INDEX SINGLE VALUE" " | IDX_TICKETS_I01 "| | |" " " | " " | |* 15 | " BITMAP INDEX SINGLE VALUE " " | TICKETS_INDEX | | |" " " |" " | | 16 | TABLE ACCESS BY INDEX ROWID " | PANELS"" " | 1| 50| 1 (0)| 00:00:01| |* 17 | INDEX UNIQUE SCAN " "" " | SYS_C0367234 " | 1| | 1 (0)| 00:00:01| | 18 | TABLE ACCESS BY INDEX ROWID " | USERS" " " | 1| 28| 1 (0)| 00:00:01| |* 19 | INDEX UNIQUE SCAN" " "" | SYS_C0038942" | 1| | 1 (0)| 00:00:01| | 20 | TABLE ACCESS BY INDEX ROWID" "" | CUSTOMERS " " | 1| 20| 1 (0)| 00:00:01| |* 21 | INDEX UNIQUE SCAN"" "" " | SYS_C8712300" | 1| | 1 (0)| 00:00:01| --------------------------------------------------------------------------------------------------------
  37. 37. STORAGE • Consider separating table and index tablespaces • Specify suitable storage parameters • PCTFREE is meaningless in indexes • logging/nologging • Extent and block size can be defined • Manage backups • Manage physical storage
  38. 38. • Index reorganization options • alter index rebuild • alter index coalesce • alter index shrink space (compact) MAINTENANCE
  39. 39. • Use DBMS_STATS • Defaults are usually best: exec dbms_stats.set_global_prefs(‘METHOD_OPT’, ‘FOR ALL COLUMNS SIZE AUTO’); exec dbms_stats.reset_global_pref_defaults; • CASCADE=TRUE structureddata.org/2008/10/14/dbms_stats-method_opt-and-for-all-indexed-columns/ GENERATING STATISTICS
  40. 40. • Introduced in 11g • Allows you to create column groups • Determines a relationship among potentially skewed data dbms_stats.create_extended_stats( ‘APP’, ‘CUSTOMERS’, ‘(BIRTHDATE, BIRTHSTONE)’); EXTENDED STATISTICS
  41. 41. oracle.sean@gmail.com sean.scott@bodybuilding.com github.com/oraclesean/oracle

×