1818IP-服务器技术教程,云服务器评测推荐,服务器系统排错处理,环境搭建,攻击防护等

当前位置:首页 - 数据库 - 正文

君子好学,自强不息!

Oracle性能优化之虚拟索引

2022-11-22 | 数据库 | admin | 535°c
A+ A-

Oracle性能优化之虚拟索引

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

下面举例进行说明:

1.创建一个测试表test

SQL>createtabletestasselect*fromdba_objects;
Table created.

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

SQL>select*fromtestwhereobject_name='STANDARD';

OWNER

------------------------------

OBJECT_NAME

--------------------------------------------------------------------

SUBOBJECT_NAMEOBJECT_IDDATA_OBJECT_IDOBJECT_TYPE

-----------------------------------------------------------------

CREATEDLAST_DDL_TIMTIMESTAMPSTATUSTGS

-----------------------------------------------------

SYS

STANDARD

888PACKAGE

19-APR-1019-APR-102003-04-18:00:00:00VALIDNNN

OWNER

------------------------------

OBJECT_NAME

--------------------------------------------------------------------

SUBOBJECT_NAMEOBJECT_IDDATA_OBJECT_IDOBJECT_TYPE

-------------------------------------------------------------------------

CREATEDLAST_DDL_TIMTIMESTAMPSTATUSTGS

-----------------------------------------------------

SYS

STANDARD

889PACKAGEBODY

19-APR-1019-APR-102010-04-19:10:22:58VALIDNNN

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

SQL>setautotracetraceonlyexplain

SQL>select*fromtestwhereobject_name='STANDARD';

ExecutionPlan

----------------------------------------------------------

Planhashvalue:1357081020

--------------------------------------------------------------------------

|Id|Operation|Name|Rows|Bytes|Cost(%CPU)|Time|

--------------------------------------------------------------------------

|0|SELECTSTATEMENT||8|1416|155(1)|00:00:02|

|*1|TABLEACCESSFULL|TEST|8|1416|155(1)|00:00:02|

--------------------------------------------------------------------------

PredicateInformation(identifiedbyoperationid):

---------------------------------------------------

1-filter("OBJECT_NAME"='STANDARD')

Note

-----

-dynamicsamplingusedforthisstatement

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

SQL>createindextest_indexontest(object_name)nosegment;Indexcreated.

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

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

SQL>setautotraceoff

SQL>selectindex_namefromdba_indexeswheretable_name='TEST'andindex_name='TEST_INDEX';

norowsselected

SQL>colOBJECT_NAMEformata20;

SQL>selectobject_name,object_typefromdba_objectswhereobject_name='TEST_INDEX';

OBJECT_NAMEOBJECT_TYPE

---------------------------------------

TEST_INDEXINDEX

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

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

SQL>setautotracetraceonlyexplainSQL>select*fromtestwhereobject_name='STANDARD';

ExecutionPlan

----------------------------------------------------------

Planhashvalue:1357081020

--------------------------------------------------------------------

|Id|Operation|Name|Rows|Bytes|Cost(%CPU)|Time|

--------------------------------------------------------------------

|0|SELECTSTATEMENT||8|1416|155(1)|00:00:02|

|*1|TABLEACCESSFULL|TEST|8|1416|155(1)|00:00:02|

--------------------------------------------------------------------

PredicateInformation(identifiedbyoperationid):

---------------------------------------------------

1-filter("OBJECT_NAME"='STANDARD')

Note

-----

-dynamicsamplingusedforthisstatement

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

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

SQL>altersessionset"_USE_NOSEGMENT_INDEXES"=true;Sessionaltered.

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

SQL>setlong900SQL>setlinesize900

SQL>select*fromtestwhereobject_name='STANDARD';

ExecutionPlan

----------------------------------------------------------

Planhashvalue:2627321457

--------------------------------------------------------------------

|Id|Operation|Name|Rows|Bytes|Cost(%CPU)|Time|

--------------------------------------------------------------------

|0|SELECTSTATEMENT||8|1416|5(0)|00:00:01|

|1|TABLEACCESSBYINDEXROWID|TEST|8|1416|5(0)|00:00:01|

|*2|INDEXRANGESCAN|TEST_INDEX|238||1(0)|00:00:01|

--------------------------------------------------------------------

PredicateInformation(identifiedbyoperationid):

---------------------------------------------------

2-access("OBJECT_NAME"='STANDARD')

Note

-----

-dynamicsamplingusedforthisstatement

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

本文来源:1818IP

本文地址:https://www.1818ip.com/post/10815.html

免责声明:本文由用户上传,如有侵权请联系删除!

发表评论

必填

选填

选填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。