在Oracle中强制使用索引

7xllpg7q  于 2023-02-15  发布在  Oracle
关注(0)|答案(6)|浏览(190)

我在一次采访中遇到了这个问题,不知道该如何回答:
有一个表的列上有一个索引,您查询:

select * from table_name where column_having_index="some value";

查询花费的时间太长,而您发现索引没有被使用。如果您认为使用索引会提高查询的性能,那么如何强制查询使用索引呢?

5vf7fwbs

5vf7fwbs1#

您可以使用优化程序提示
select /*+ INDEX(table_name index_name) */ from table
More on using optimizer hints

ajsxfq5m

ajsxfq5m2#

索引未被使用的原因可能有 * 许多 。即使在您*specify hints**之后,Oracle优化器仍有可能会有不同的想法,决定不使用索引。您需要仔细检查EXPLAIN PLAN部分,看看使用INDEX和不使用INDEX的语句的成本是多少。
假设为Oracle uses CBO。通常,如果优化程序认为使用INDEX的成本很高,即使您在提示中指定了它,优化程序也会忽略并继续进行全表扫描。您的第一个操作应该是检查DBA_INDEXES以了解统计信息何时为LAST_ANALYZED。如果未分析,则可以设置table,index以进行分析。

begin 
   DBMS_STATS.GATHER_INDEX_STATS ( OWNNAME=>user
                                 , INDNAME=>IndexName);
end;

table用的。

begin 
   DBMS_STATS.GATHER_TABLE_STATS ( OWNNAME=>user
                                 , TABNAME=>TableName);
end;

在极端情况下,您可以尝试自己设置统计信息。

44u64gxh

44u64gxh3#

如果您认为使用索引查询的性能会更好,那么如何强制查询使用索引呢?
首先,您当然要验证索引对于返回完整的数据集给出了更好的结果,对吗?
索引提示是这里的关键,但指定它的最新方法是使用列命名方法,而不是索引命名方法。在您的情况下,可以用途:

select /*+ index(table_name (column_having_index)) */ *
from   table_name
where  column_having_index="some value";

在更复杂的情况下,您可能...

select /*+ index(t (t.column_having_index)) */ *
from   my_owner.table_name t,
       ...
where  t.column_having_index="some value";

关于复合索引,我不确定你是否需要指定所有的列,但这似乎是个好主意,请参见www.example.com中http://docs.oracle.com/cd/E11882_01/server.112/e26088/sql_elements006.htm#autoId18关于多个index_specs和使用index_合并作为多个索引的文档,以及www.example.com中http://docs.oracle.com/cd/E11882_01/server.112/e26088/sql_elements006.htm#BABGFHCH关于index_specs中多个列的规范。

xzlaal3s

xzlaal3s4#

column_having_index上有一个适当的索引,使用它实际上提高了性能,但Oracle没有使用它......

您应该收集表的统计信息,以便优化程序发现索引访问可以提供帮助。使用直接提示不是一个好的做法。

xtupzzrd

xtupzzrd5#

我尝试了许多格式,但只有一种有效:

select /*+INDEX(e,dept_idx)*/ * from emp e;
y3bcpkx1

y3bcpkx16#

您可以用途:

WITH index = ...

more info

相关问题