Download - Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

Transcript
Page 1: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

INDEXING STRATEGIESSean Scott

Oracle DBA, Bodybuilding.com

Page 3: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

B-TREE INDEXES

• Most common type of index

• Data is ordered within the index

• Consists of branches and leaves

Page 4: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

B-TREE INDEXES

Page 5: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

B-TREE INDEXES

• Options include

• Unique

• Descending

• Reverse Key

• Index Organized Tables

• Composite, Covering, Concatenated

• Compressed

Page 6: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

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

Page 7: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

REVERSE KEY INDEXES

• Two implementations:

• last_updated_date in a customer order table

• Sequentially updated primary key

Page 8: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

REVERSE KEY INDEXES

• Things to watch for:

• Increase in db sequential read wait events

• Backup time increase

• Space use increase

Page 9: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

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

Page 10: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

COMPOSITE INDEXES

• Sometimes known as covering or concatenated

• Consist of more than one column

• Leading column is important

Page 11: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

COMPOSITE INDEXES

create index test_i1 on test(col1);

create index test_i2 on test(col1, col2);

Page 12: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

COMPOSITE INDEXES

• Choosing a leading column

• High cardinality?

• Low cardinality?

• Most frequently accessed

Page 13: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

• The Poor-Man’s IOT

•Use to improve performance of select by reducing I/O

COVERING INDEXES

Page 14: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

 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 |-------------------------------------------------------------------------------------------

Page 15: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

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 |-----------------------------------------------------------------------------------

Page 16: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

COMPRESSED KEY INDEXES

• Leading columns have low cardinality

• Save space

• Improve performance

Page 17: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

BITMAP INDEXES

• Index on low cardinality data

• Take up little space

• Bitmap join

• Typically found in data warehouse environments

Page 18: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

FUNCTION BASED, INDEXED VIRTUAL

• Index on a database function (predefined, user written)

• Allows index lookups when a function is used

• Both store the derived value in the index

Page 19: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

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

Page 20: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

VIRTUAL INDEXES

• Only visible to the optimizer

• Used for evaluating an indexes usefulness

Page 21: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

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

Page 22: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

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 COL1TEST TEST_I2 COL1

Page 23: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

CLUSTER INDEXES

• B-Tree Cluster Index

• Hash Cluster Index

• Hash clusters can exist on a single table

Page 24: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

PARTITIONED INDEXES

• Global Partitioned

• Crosses partitions

• Exists on whole table

• Local Partitioned

• Unique to each partition

• Watch out for non-partitioned indexes on partitions

Page 25: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

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

Page 26: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

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

Page 27: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

PARTITIONED INDEXES

Local partitionPartition index unusablePartition index unusablePartitions involved unusablePartition index unusableNo effect on indexNo effect on index

Global or non-partitionEntire index unusableEntire index unusableEntire index unusableEntire index unusableEntire index unusableEntire index unusable

OperationSplitMoveMergeExchangeTruncateDrop

Page 28: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

WHAT TO INDEX

• Primary keys

• Unique keys

• Foreign keys

• Columns frequently used in where, distinct, and order by clauses

• Columns often queried together

Page 29: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

Index all that should be, and no more.

Page 30: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

If in doubt, b-tree is probably safest.

Page 31: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

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

Page 32: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

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));

Page 33: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

select table_name, index_name from dba_indexes where table_name like 'TEST%';

TEST2 SYS_C0015135TEST1 TEST1_P

Page 34: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

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

Page 35: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

• Pick a convention and stick to it!

•tablename_p•tablename_un•tablename_in•tablename_fn•tablename_bn• ...etc

NAMING CONVENTION

Page 36: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

--------------------------------------------------------------------------------------------------------| 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|--------------------------------------------------------------------------------------------------------

Page 37: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

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

Page 38: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

• Index reorganization options

•alter index rebuild

•alter index coalesce

•alter index shrink space (compact)

MAINTENANCE

Page 39: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

• 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

Page 40: Indexing Strategies for Oracle Databases - Beyond the Create Index Statement

• 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