Indexes

Creating Indexes

=================

-- 1. Create a basic B-tree index on a single column

CREATE INDEX idx_emp_name ON employees(emp_name);

 

-- 2. Create a unique index

CREATE UNIQUE INDEX idx_unique_email ON employees(email);

 

-- 3. Create a composite index on multiple columns

CREATE INDEX idx_emp_dept ON employees(department_id, emp_name);

 

-- 4. Create a bitmap index (useful for low cardinality columns)

CREATE BITMAP INDEX idx_gender ON employees(gender);

 

-- 5. Create a reverse key index (helps distribute inserts)

CREATE INDEX idx_reverse_emp_id ON employees(emp_id) REVERSE;

 

-- 6. Create a function-based index

CREATE INDEX idx_upper_emp_name ON employees(UPPER(emp_name));

 

-- 7. Create an index on a table partition

CREATE INDEX idx_part ON sales(order_date) LOCAL;

 

-- 8. Create an index with parallelism for faster build

CREATE INDEX idx_parallel_emp_name ON employees(emp_name) PARALLEL 4;

 

-- 9. Create an index with tablespace specification

CREATE INDEX idx_ts_emp_name ON employees(emp_name) TABLESPACE idx_ts;

 

-- 10. Create an index with storage parameters

CREATE INDEX idx_storage ON employees(emp_name) STORAGE (INITIAL 64K NEXT 64K);

 

-- 11. Create a compressed index to save space

CREATE INDEX idx_comp_emp_name ON employees(emp_name) COMPRESS 2;

 

-- 12. Create a domain index (e.g., Oracle Text)

CREATE INDEX idx_text_doc ON documents(content) INDEXTYPE IS CTXSYS.CONTEXT;

 

-- 13. Create a bitmap join index (in data warehouse)

CREATE BITMAP INDEX idx_bm_join ON sales(customer_id);

 

-- 14. Create a function-based index with expression

CREATE INDEX idx_trunc_order_date ON sales(TRUNC(order_date));

 

-- 15. Create an invisible index (used for testing optimizer impact)

CREATE INDEX idx_invisible ON employees(emp_name) INVISIBLE;

 

-- 16. Create a descending index

CREATE INDEX idx_desc_salary ON employees(salary DESC);

 

-- 17. Create a unique index on concatenation of columns

CREATE UNIQUE INDEX idx_unique_name_dept ON employees(emp_name || department_id);

 

-- 18. Create a global partitioned index

CREATE INDEX idx_global_part ON sales(order_date) GLOBAL PARTITION BY RANGE (order_date) (

  PARTITION p1 VALUES LESS THAN (TO_DATE('01-JAN-2020','DD-MON-YYYY')),

  PARTITION p2 VALUES LESS THAN (MAXVALUE)

);

 

-- 19. Create a compressed function-based index

CREATE INDEX idx_comp_upper_name ON employees(UPPER(emp_name)) COMPRESS 1;

 

-- 20. Create an index on a LOB column (if supported)

CREATE INDEX idx_lob_content ON documents(content) LOB (content) STORE AS SECUREFILE;

 

Altering and Managing Indexes

=============================

-- 21. Rebuild an index (to defragment and optimize)

ALTER INDEX idx_emp_name REBUILD;

 

-- 22. Rebuild an index in parallel

ALTER INDEX idx_emp_name REBUILD PARALLEL 4;

 

-- 23. Rebuild an index with tablespace change

ALTER INDEX idx_emp_name REBUILD TABLESPACE idx_ts;

 

-- 24. Coalesce an index (merge leaf blocks without rebuilding)

ALTER INDEX idx_emp_name COALESCE;

 

-- 25. Enable parallelism on an existing index

ALTER INDEX idx_emp_name PARALLEL 8;

 

-- 26. Disable parallelism on an index

ALTER INDEX idx_emp_name NOPARALLEL;

 

-- 27. Rename an index

ALTER INDEX idx_emp_name RENAME TO idx_emp_name_new;

 

-- 28. Drop an index

DROP INDEX idx_emp_name;

 

-- 29. Mark an index as unusable

ALTER INDEX idx_emp_name UNUSABLE;

 

-- 30. Make an unusable index usable again by rebuilding

ALTER INDEX idx_emp_name REBUILD;

 

-- 31. Alter index visibility (make visible)

ALTER INDEX idx_invisible VISIBLE;

 

-- 32. Alter index visibility (make invisible)

ALTER INDEX idx_emp_name INVISIBLE;

 

-- 33. Change storage parameters of an index

ALTER INDEX idx_emp_name STORAGE (INITIAL 128K NEXT 128K);

 

-- 34. Change tablespace of an index by rebuild

ALTER INDEX idx_emp_name REBUILD TABLESPACE new_ts;

 

-- 35. Analyze index statistics

ANALYZE INDEX idx_emp_name COMPUTE STATISTICS;

 

-- 36. Gather optimizer stats for index

BEGIN

  DBMS_STATS.GATHER_INDEX_STATS('HR', 'IDX_EMP_NAME');

END;

/

 

-- 37. Move index to a new tablespace

ALTER INDEX idx_emp_name REBUILD TABLESPACE idx_ts_new;

 

-- 38. Set index logging on/off

ALTER INDEX idx_emp_name LOGGING;

 

-- 39. Change index monitoring status to ON

ALTER INDEX idx_emp_name MONITORING USAGE;

 

-- 40. Check index usage statistics

SELECT index_name, leaf_blocks, distinct_keys FROM user_indexes WHERE index_name = 'IDX_EMP_NAME';

 

Index Usage and Info Queries

=============================

-- 41. List all indexes on a table

SELECT index_name, index_type FROM user_indexes WHERE table_name = 'EMPLOYEES';

 

-- 42. Find columns used in an index

SELECT index_name, column_name, column_position FROM user_ind_columns WHERE index_name = 'IDX_EMP_NAME';

 

-- 43. Show index size and stats

SELECT index_name, leaf_blocks, clustering_factor FROM user_indexes WHERE index_name = 'IDX_EMP_NAME';

 

-- 44. Show indexes owned by a user/schema

SELECT index_name, table_name FROM user_indexes WHERE owner = 'HR';

 

-- 45. Check if an index is unique

SELECT index_name, uniqueness FROM user_indexes WHERE index_name = 'IDX_UNIQUE_EMAIL';

 

-- 46. Find indexes with bitmap type

SELECT index_name FROM user_indexes WHERE index_type = 'BITMAP';

 

-- 47. Show index status (VALID, UNUSABLE)

SELECT index_name, status FROM user_indexes WHERE table_name = 'EMPLOYEES';

 

-- 48. Check if an index is visible or invisible

SELECT index_name, visibility FROM user_indexes WHERE index_name = 'IDX_EMP_NAME';

 

-- 49. Find index monitoring status

SELECT index_name, monitoring FROM user_indexes WHERE index_name = 'IDX_EMP_NAME';

 

-- 50. List function-based indexes on a table

SELECT index_name FROM user_indexes WHERE table_name = 'EMPLOYEES' AND FUNCTION_BASED = 'YES';

 

-- 51. Show index columns with data types

SELECT ic.index_name, ic.column_name, c.data_type

FROM user_ind_columns ic

JOIN user_tab_columns c ON ic.table_name = c.table_name AND ic.column_name = c.column_name

WHERE ic.index_name = 'IDX_EMP_NAME';

 

-- 52. Check global vs local partitioned index

SELECT index_name, partitioned, global_stats, local_stats FROM user_indexes WHERE table_name = 'SALES';

 

-- 53. Check compression status of indexes

SELECT index_name, compression FROM user_indexes WHERE table_name = 'EMPLOYEES';

 

-- 54. Find indexes with high clustering factor (less efficient)

SELECT index_name, clustering_factor FROM user_indexes WHERE table_name = 'EMPLOYEES' ORDER BY clustering_factor DESC;

 

-- 55. Check index columns length (for variable length columns)

SELECT index_name, column_name, column_length FROM user_ind_columns WHERE index_name = 'IDX_EMP_NAME';

 

-- 56. Show largest indexes by size

SELECT index_name, (bytes/1024/1024) AS size_mb FROM user_segments WHERE segment_type = 'INDEX' ORDER BY bytes DESC;

 

-- 57. Check index for invalid entries (user_errors)

SELECT * FROM user_errors WHERE name = 'IDX_EMP_NAME';

 

-- 58. List indexes created within last 7 days

SELECT index_name, created FROM user_objects WHERE object_type = 'INDEX' AND created > SYSDATE - 7;

 

-- 59. Show index fragmentation using DBA_EXTENTS

SELECT segment_name, COUNT(*) AS extent_count FROM dba_extents WHERE segment_name = 'IDX_EMP_NAME' GROUP BY segment_name;

 

-- 60. Get index root block address for diagnostics

SELECT index_name, root_block_addr FROM user_indexes WHERE index_name = 'IDX_EMP_NAME';

 

Using Indexes with Queries and Optimization

===========================================

-- 61. Explain plan using an index

EXPLAIN PLAN FOR SELECT * FROM employees WHERE emp_name = 'John';

 

-- 62. Force use of an index in a query

SELECT /*+ INDEX(employees idx_emp_name) */ * FROM employees WHERE emp_name = 'John';

 

-- 63. Force full table scan ignoring indexes

SELECT /*+ FULL(employees) */ * FROM employees WHERE emp_name = 'John';

 

-- 64. Check if an index is used for a query

SELECT * FROM table(dbms_xplan.display_cursor());

 

-- 65. Create a bitmap join index to speed join queries

CREATE BITMAP INDEX idx_bm_join_customer ON sales(customer_id);

 

-- 66. Create an index to optimize ORDER BY query

CREATE INDEX idx_emp_name_sort ON employees(emp_name);

 

-- 67. Use index monitoring to see if index is used

ALTER INDEX idx_emp_name MONITORING USAGE;

 

-- 68. Query to check if monitored index is used

SELECT * FROM v$object_usage WHERE index_name = 'IDX_EMP_NAME';

 

-- 69. Drop monitoring on index after analysis

ALTER INDEX idx_emp_name NOMONITORING USAGE;

 

-- 70. Use an index to speed up LIKE queries (on prefix)

CREATE INDEX idx_emp_name_like ON employees(emp_name);

 

-- 71. Create a function-based index to speed up LOWER() queries

CREATE INDEX idx_lower_email ON employees(LOWER(email));

 

-- 72. Query with function using index

SELECT * FROM employees WHERE LOWER(email) = 'abc@xyz.com';

 

-- 73. Use index to optimize BETWEEN queries

CREATE INDEX idx_order_date ON sales(order_date);

 

-- 74. Partitioned index for partitioned tables

CREATE INDEX idx_partitioned ON sales(order_date) LOCAL;

 

-- 75. Use invisible index to test optimizer impact

CREATE INDEX idx_test_inv ON employees(emp_name) INVISIBLE;

 

-- 76. Drop unused index to save space

DROP INDEX idx_unused;

 

-- 77. Create compressed index for large tables to save space

CREATE INDEX idx_compressed ON big_table(col1, col2) COMPRESS 3;

 

-- 78. Use index for EXISTS subquery optimization

SELECT * FROM employees e WHERE EXISTS (SELECT 1 FROM departments d WHERE d.dept_id = e.department_id);

 

-- 79. Create index on foreign key column to improve join performance

CREATE INDEX idx_fk_dept_id ON employees(department_id);

 

-- 80. Create index on computed column for performance

ALTER TABLE employees ADD (full_name GENERATED ALWAYS AS (emp_name || ' ' || last_name) VIRTUAL);

CREATE INDEX idx_full_name ON employees(full_name);

 

Advanced Index Usage and Maintenance

====================================

-- 81. Drop index if exists (PL/SQL block)

BEGIN

  EXECUTE IMMEDIATE 'DROP INDEX idx_emp_name';

EXCEPTION

  WHEN OTHERS THEN

    IF SQLCODE != -942 THEN

      RAISE;

    END IF;

END;

/

 

-- 82. Use DBMS_STATS to gather index stats

BEGIN

  DBMS_STATS.GATHER_INDEX_STATS('HR', 'IDX_EMP_NAME');

END;

/

 

-- 83. Rebuild index online (no table locking)

ALTER INDEX idx_emp_name REBUILD ONLINE;

 

-- 84. Create index with pctfree parameter

CREATE INDEX idx_pctfree ON employees(emp_name) PCTFREE 10;

 

-- 85. Create index with caching option

CREATE INDEX idx_cache ON employees(emp_name) CACHE;

 

-- 86. Create index with NOLOGGING (for faster rebuild)

CREATE INDEX idx_nolog ON employees(emp_name) NOLOGGING;

 

-- 87. Create index with parallel degree 16

CREATE INDEX idx_parallel16 ON employees(emp_name) PARALLEL 16;

 

-- 88. Check if index is global or local partitioned

SELECT index_name, partitioned, partitioning_type FROM user_indexes WHERE index_name = 'IDX_GLOBAL_PART';

 

-- 89. Create an index on XMLType column (using XMLIndex)

CREATE INDEX idx_xml_content ON xml_table(xml_column) INDEXTYPE IS CTXSYS.XMLINDEX;

 

-- 90. Create an invisible unique index (for testing uniqueness)

CREATE UNIQUE INDEX idx_invisible_unique ON employees(email) INVISIBLE;

 

-- 91. Check index rebuild progress (Oracle 12c+)

SELECT operation, sofar, totalwork, units FROM v$session_longops WHERE opname LIKE '%IDX_EMP_NAME%';

 

-- 92. Drop unusable index partitions

ALTER INDEX idx_partitioned DROP PARTITION p1;

 

-- 93. Create a bitmap index with segment creation deferred

CREATE BITMAP INDEX idx_bitmap_def ON employees(status) NOSEGMENT;

 

-- 94. Create a unique index with global partitioning

CREATE UNIQUE INDEX idx_global_unique ON sales(order_id) GLOBAL PARTITION BY HASH (order_id) PARTITIONS 4;

 

-- 95. Create a domain index (e.g., for spatial data)

CREATE INDEX idx_spatial_geom ON locations(geometry) INDEXTYPE IS MDSYS.SPATIAL_INDEX;

 

-- 96. Query to check invalid indexes in schema

SELECT index_name FROM user_indexes WHERE status = 'UNUSABLE';

 

-- 97. Query to check indexes with high leaf_blocks

SELECT index_name, leaf_blocks FROM user_indexes WHERE leaf_blocks > 1000;

 

-- 98. Create index on virtual column

ALTER TABLE employees ADD (emp_initials GENERATED ALWAYS AS (SUBSTR(emp_name,1,1) || SUBSTR(last_name,1,1)) VIRTUAL);

CREATE INDEX idx_emp_initials ON employees(emp_initials);

 

-- 99. Use index hint with table alias

SELECT /*+ INDEX(e idx_emp_name) */ e.emp_name FROM employees e WHERE e.emp_name = 'John';

 

-- 100. Drop all indexes on a table (PL/SQL block)

DECLARE

  CURSOR c IS SELECT index_name FROM user_indexes WHERE table_name = 'EMPLOYEES';

BEGIN

  FOR r IN c LOOP

    EXECUTE IMMEDIATE 'DROP INDEX ' || r.index_name;

  END LOOP;

END;

/

 

 

 

No comments:

Post a Comment