我在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_name
而dml_type
也没有影响。
上述查询大约需要30到40秒来检索大约2500行。
我查看了解释计划,但无法看到正在使用amendments
和table_name
dml_type
上的索引。
以下是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';
是否有人可以建议为什么table_name
,dml_type
和column_name
索引未在上述查询中使用?
答案 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)