Oracle性能优化之虚拟索引

数据库 Oracle
虚拟索引是定义在数据字典中的伪索引,但没有相关的索引段。虚拟索引的目的是模拟索引的存--而不用真实的创建一个完整索引。这允许开发者创建虚拟索引来查看相关执行计划而不用等到真实创建完索引才能查看索引对执行计划的影响,并且不会增加存储空间的使用。

[[201247]]

虚拟索引是定义在数据字典中的伪索引,但没有相关的索引段。虚拟索引的目的是模拟索引的存--而不用真实的创建一个完整索引。这允许开发者创建虚拟索引来查看相关执行计划而不用等到真实创建完索引才能查看索引对执行计划的影响,并且不会增加存储空间的使用。如果我们观察到优化器生成了一个昂贵的执行计划并且SQL调整指导建议我们对某些的某列创建索引,但在生产数据库环境中创建索引与测试并不总是可以操作。我们需要确保创建的索引将不会对数据库中的其它查询产生负面影响,因此可以使用虚拟索引。

下面举例进行说明:

1.创建一个测试表test

 

  1. SQL> create table test as select * from dba_objects; 
  2. Table created.

2.从表test查询object_name等于standard的记录

  1. SQL> select * from test where object_name='STANDARD'
  2.  
  3. OWNER 
  4.  
  5. ------------------------------ 
  6.  
  7. OBJECT_NAME 
  8.  
  9. -------------------------------------------------------------------- 
  10.  
  11. SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE 
  12.  
  13. ------------------------------ ---------- -------------- ----------- 
  14.  
  15. CREATED LAST_DDL_TIM TIMESTAMP STATUS T G S 
  16.  
  17. ------------ ------------ ------------------- ------- - - - 
  18.  
  19. SYS 
  20.  
  21. STANDARD 
  22.  
  23. 888 PACKAGE 
  24.  
  25. 19-APR-10 19-APR-10 2003-04-18:00:00:00 VALID N N N 
  26.  
  27. OWNER 
  28.  
  29. ------------------------------ 
  30.  
  31. OBJECT_NAME 
  32.  
  33. -------------------------------------------------------------------- 
  34.  
  35. SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE 
  36.  
  37. ------------------------------ ---------- -------------- ------------------- 
  38.  
  39. CREATED LAST_DDL_TIM TIMESTAMP STATUS T G S 
  40.  
  41. ------------ ------------ ------------------- ------- - - - 
  42.  
  43. SYS 
  44.  
  45. STANDARD 
  46.  
  47. 889 PACKAGE BODY 
  48.  
  49. 19-APR-10 19-APR-10 2010-04-19:10:22:58 VALID N N N 

3.查询上面查询的执行计划

  1. SQL> set autotrace traceonly explain 
  2.  
  3. SQL> select * from test where object_name='STANDARD'
  4.  
  5. Execution Plan 
  6.  
  7. ---------------------------------------------------------- 
  8.  
  9. Plan hash value: 1357081020 
  10.  
  11. -------------------------------------------------------------------------- 
  12.  
  13. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | 
  14.  
  15. -------------------------------------------------------------------------- 
  16.  
  17. | 0 | SELECT STATEMENT | | 8 | 1416 | 155 (1)| 00:00:02 | 
  18.  
  19. |* 1 | TABLE ACCESS FULL| TEST | 8 | 1416 | 155 (1)| 00:00:02 | 
  20.  
  21. -------------------------------------------------------------------------- 
  22.  
  23. Predicate Information (identified by operation id): 
  24.  
  25. --------------------------------------------------- 
  26.  
  27. 1 - filter("OBJECT_NAME"='STANDARD'
  28.  
  29. Note 
  30.  
  31. ----- 
  32.  
  33. dynamic sampling used for this statement 

 

4.在表test的object_name列上创建一个虚拟索引

  1. SQL> create index test_index on test(object_name) nosegment;Index created. 

为了创建虚拟索引必须在create index语句中指定nosegment子句,并且不会创建索引段。

5.来验证虚拟索引不会创建索引段

  1. SQL> set autotrace off 
  2.  
  3. SQL> select index_name from dba_indexes where table_name = 'TEST' and index_name = 'TEST_INDEX'
  4.  
  5. no rows selected 
  6.  
  7. SQL> col OBJECT_NAME format a20; 
  8.  
  9. SQL> select object_name, object_type from dba_objects where object_name = 'TEST_INDEX'
  10.  
  11. OBJECT_NAME OBJECT_TYPE 
  12.  
  13. -------------------- ------------------- 
  14.  
  15. TEST_INDEX INDEX 

 

从上面的结果可以看到索引对象已经创建,但没有创建索引段。

6.重新执行sql查看创建的虚拟索引是否被使用

  1. SQL> set autotrace traceonly explainSQL> select * from test where object_name='STANDARD'
  2.  
  3. Execution Plan 
  4.  
  5. ---------------------------------------------------------- 
  6.  
  7. Plan hash value: 1357081020 
  8.  
  9. -------------------------------------------------------------------- 
  10.  
  11. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | 
  12.  
  13. -------------------------------------------------------------------- 
  14.  
  15. | 0 | SELECT STATEMENT | | 8 | 1416 | 155 (1)| 00:00:02 | 
  16.  
  17. |* 1 | TABLE ACCESS FULL| TEST | 8 | 1416 | 155 (1)| 00:00:02 | 
  18.  
  19. -------------------------------------------------------------------- 
  20.  
  21. Predicate Information (identified by operation id): 
  22.  
  23. --------------------------------------------------- 
  24.  
  25. 1 - filter("OBJECT_NAME"='STANDARD'
  26.  
  27. Note 
  28.  
  29. ----- 
  30.  
  31. dynamic sampling used for this statement 

 

从上面的执行计划可以清楚地看到创建的虚拟索引并没有被使用。

7.为了能使用所创建的虚拟索引,需要将_USE_NOSEGMENT_INDEXES设置为true

  1. SQL> alter session set "_USE_NOSEGMENT_INDEXES" = true;Session altered. 

8.重新执行sql查看创建的虚拟索引是否被使用

  1. SQL> set long 900SQL> set linesize 900 
  2.  
  3. SQL> select * from test where object_name='STANDARD'
  4.  
  5. Execution Plan 
  6.  
  7. ---------------------------------------------------------- 
  8.  
  9. Plan hash value: 2627321457 
  10.  
  11. -------------------------------------------------------------------- 
  12.  
  13. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | 
  14.  
  15. -------------------------------------------------------------------- 
  16.  
  17. | 0 | SELECT STATEMENT | | 8 | 1416 | 5 (0)| 00:00:01 | 
  18.  
  19. | 1 | TABLE ACCESS BY INDEX ROWID| TEST | 8 | 1416 | 5 (0)| 00:00:01 | 
  20.  
  21. |* 2 | INDEX RANGE SCAN | TEST_INDEX | 238 | | 1 (0)| 00:00:01 | 
  22.  
  23. -------------------------------------------------------------------- 
  24.  
  25. Predicate Information (identified by operation id): 
  26.  
  27. --------------------------------------------------- 
  28.  
  29. 2 - access("OBJECT_NAME"='STANDARD'
  30.  
  31. Note 
  32.  
  33. ----- 
  34.  
  35. dynamic sampling used for this statement 

 

从上面的执行计划可以看到当设置隐含参数_USE_NOSEGMENT_INDEXES后,优化器将会使用创建的虚拟索引。在使用虚拟索引需要注意,我们可以分析虚拟索引,但不能重建虚拟索引,如果重建虚拟索引会收到ORA-8114: "User attempted to alter a fake index"错误提示,可以删除虚拟索引。

责任编辑:庞桂玉 来源: Oracle疑点通
相关推荐

2009-06-30 11:23:02

性能优化

2018-01-09 16:56:32

数据库OracleSQL优化

2021-07-16 23:01:03

SQL索引性能

2021-07-26 18:23:23

SQL策略优化

2010-06-03 09:24:46

Oracle

2009-10-20 18:32:25

Oracle 10g

2015-09-14 09:45:58

虚拟化网络网络性能

2010-10-27 13:47:50

Oracle索引

2018-06-07 08:54:01

MySQL性能优化索引

2020-10-19 19:45:58

MySQL数据库优化

2010-04-14 12:51:10

Oracle性能

2021-07-29 14:20:34

网络优化移动互联网数据存储

2022-02-16 14:10:51

服务器性能优化Linux

2021-11-29 11:13:45

服务器网络性能

2010-04-23 14:48:26

Oracle性能优化

2019-12-13 10:25:08

Android性能优化启动优化

2011-07-11 15:26:49

性能优化算法

2013-02-20 14:32:37

Android开发性能

2023-07-19 12:24:48

C++constexpr​语句

2009-06-03 10:32:36

Oracle性能优化分区技术
点赞
收藏

51CTO技术栈公众号