连接到另一个表时未使用 Oracle 索引

发布于 2024-11-19 11:12:36 字数 1786 浏览 2 评论 0原文

我在 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 行。

我查看了解释计划,看不到正在使用 table_namedml_typeamendments 索引。

Explain plain for oracle joins

以下是 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';

解释 ANSI 连接的计划

任何人都可以建议为什么 table_namedml_type 和上述查询中未使用 column_name 索引?

I have the following sql being run on an Oracle 10g database:

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';

There are the following indexes that have been created:

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);

I have also tried using ANSI joins (the below sql) but this does not use the indexes either, placing upper() around the table_name and dml_type also has no affect.

The above query is taking approximately 30 - 40 secs to retrieve around 2500 rows.

I looked at the explain plan and can't see that the index on amendments for table_name and dml_type are being used.

Explain plain for oracle joins attached

Below is the ANSI explain plan for:

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

Could any one advise why the table_name, dml_type and column_name indexes aren't being used in the above query?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迷鸟归林 2024-11-26 11:12:36

如果您实际上按照您所说的那样运行了此命令:

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);

If you have actually run this as you say:

create index amendments_dmp_type_upper on amendments upper(dmp_type);

then what you have actually created is an index on amendments(dmp_type) without the upper function!

The correct syntax is:

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

Perhaps surprisingly, your statement works but the word "upper" is treated as a table alias - this works too:

create index amendments_dmp_type_upper on amendments foo(dmp_type);
病女 2024-11-26 11:12:36

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

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)

I'm not an expert on Oracle, but it appears that it's not using (or unable to use) INDEX Merging. This means you need composite indexes.

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文