加入另一个表时未使用Oracle索引

时间:2011-07-08 10:18:33

标签: sql oracle10g indexing

我在Oracle 10g数据库上运行以下sql:

select  /*+ ALL_ROWS */
       to_number(cv.old_value) as cv_id,
       to_number(job.old_value) as job_id
  from amendments,
       amnddets cv,
       amnddets job
 where amendments.table_name = 'TIMESHEET_LAYER'
   and amendments.dml_type = 'D'
   and cv.amnd_id = amendments.amnd_id 
   and cv.column_name = 'CV_ID'
   and job.amnd_id = amendments.amnd_id
   and job.column_name = 'JOB_ID';

已创建以下索引:

create index amendments_dmp_type_upper on amendments upper(dmp_type);
create index amendments_table_name_upper on amendments upper(table_name);
create index amendments_pk on amendments (amnd_id);
create index amended_column_name_idx on amnddets (column_name);
create index amnddets_amnd_id_idx on amnddets (amnd_id);

我也尝试过使用ANSI连接(下面的sql),但这也没有使用索引,upper()周围放置table_namedml_type也没有影响。

上述查询大约需要30到40秒来检索大约2500行。

我查看了解释计划,但无法看到正在使用amendmentstable_name dml_type上的索引。

Explain plain for oracle joins attached

以下是ANSI解释计划:

select  /*+ ALL_ROWS */
       to_number(cv.old_value) as cv_id,
       to_number(job.old_value) as job_id
  from amendments
  JOIN amnddets cv on cv.amnd_id = amendments.amnd_id and cv.column_name = 'CV_ID'
  JOIN amnddets job on job.amnd_id = amendments.amnd_id and job.column_name = 'JOB_ID'
 where upper(amendments.table_name) = 'TIMESHEET_LAYER'
   and amendments.dml_type = 'D';

Explain plan for the ANSI joins

是否有人可以建议为什么table_namedml_typecolumn_name索引未在上述查询中使用?

2 个答案:

答案 0 :(得分:2)

如果你实际上按照你的说法运行了这个:

create index amendments_dmp_type_upper on amendments upper(dmp_type);

那么您实际创建的是amendments(dmp_type)上没有upper函数的索引!

正确的语法是:

create index amendments_dmp_type_upper on amendments (upper(dmp_type));

也许令人惊讶的是,你的陈述有效,但“upper”这个词被视为表别名 - 这也有效:

create index amendments_dmp_type_upper on amendments foo(dmp_type);

答案 1 :(得分:1)

我不是Oracle的专家,但它似乎没有使用(或无法使用)INDEX Merging。这意味着您需要复合索引。

create index amnddets_column_name_amnd_id_idx on amnddets (column_name, amnd_id);

create index amendments_dml_type_table_name_amnd_id_idx on amendments (dml_type, table_name, amnd_id)