Vij*_*jay 33 sql oracle indexing sqlplus
我在一次采访中遇到了这个问题,并且不知道如何回答:
有一个表在列上有索引,您查询:
select * from table_name where column_having_index="some value";
Run Code Online (Sandbox Code Playgroud)
查询花费的时间太长,您发现索引未被使用.如果您认为使用索引查询的性能会更好,那么您如何强制查询使用索引?
Ren*_*ene 44
您可以使用优化程序提示
select /*+ INDEX(table_name index_name) */ from table 等等...
有关使用优化程序提示的更多信息:http: //download.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm
Gur*_*uru 13
索引未被使用可能有很多原因.即使在指定提示之后,Oracle优化器也有可能不这么认为并且决定不使用Index.您需要浏览EXPLAIN PLAN部分,看看使用INDEX和没有INDEX的语句的成本是多少.
假设Oracle使用CBO.大多数情况下,如果优化器认为INDEX的成本很高,即使您在提示中指定它,优化器也会忽略并继续进行全表扫描.您的第一个操作应该是检查DBA_INDEXES以了解统计信息何时为LAST_ANALYZED.如果没有分析,可以设置表,索引进行分析.
begin
DBMS_STATS.GATHER_INDEX_STATS ( OWNNAME=>user
, INDNAME=>IndexName);
end;
Run Code Online (Sandbox Code Playgroud)
对于表.
begin
DBMS_STATS.GATHER_TABLE_STATS ( OWNNAME=>user
, TABNAME=>TableName);
end;
Run Code Online (Sandbox Code Playgroud)
在极端情况下,您可以尝试自行设置统计信息.
Dav*_*dge 12
如果您认为使用索引查询的性能会更好,那么您如何强制查询使用索引?
首先,您当然要验证索引是否为返回完整数据集提供了更好的结果,对吧?
索引提示是这里的关键,但更新的指定方法是使用列命名方法而不是索引命名方法.在您的情况下,您将使用:
select /*+ index(table_name (column_having_index)) */ *
from table_name
where column_having_index="some value";
Run Code Online (Sandbox Code Playgroud)
在更复杂的情况下,你可能......
select /*+ index(t (t.column_having_index)) */ *
from my_owner.table_name t,
...
where t.column_having_index="some value";
Run Code Online (Sandbox Code Playgroud)
关于复合索引,我不确定您是否需要指定所有列,但这似乎是一个好主意.请参阅http://dsocs.oracle.com/cd/E11882_01/server.112/e26088/sql_elements006.htm#autoId18上有关多个index_specs 的文档,并将index_combine用于多个索引,此处为http://docs.oracle. com/cd/E11882_01/server.112/e26088/sql_elements006.htm#BABGFHCH用于index_spec中多列的规范.