无法在 PL/SQL 过程期间禁用索引

发布于 2024-09-01 08:36:51 字数 2159 浏览 3 评论 0原文

我编写了一个 PL/SQL 过程,如果首先禁用索引,然后在完成后重建索引,该过程将会受益。 现有线程建议采用这种方法:

alter session set skip_unusable_indexes = true;

alter index your_index unusable;

[do import ]

alter index your_index rebuild;

但是,我在第一个 alter index 语句中收到以下错误:

SQL Error: ORA-14048: a partition maintenance operation may not be combined with other operations
ORA-06512: [...]
14048. 00000 -  "a partition maintenance operation may not be combined with other operations"
*Cause:    ALTER TABLE or ALTER INDEX statement attempted to combine
           a partition maintenance operation (e.g. MOVE PARTITION) with some
           other operation (e.g. ADD PARTITION or PCTFREE which is illegal
*Action:   Ensure that a partition maintenance operation is the sole
           operation specified in ALTER TABLE or ALTER INDEX statement;
           operations other than those dealing with partitions,
           default attributes of partitioned tables/indices or
           specifying that a table be renamed (ALTER TABLE RENAME) may be
           combined at will

问题索引的定义如下:

CREATE INDEX A11_IX1 ON STREETS ("SHAPE")
  INDEXTYPE IS "SDE"."ST_SPATIAL_INDEX" PARAMETERS
  ('ST_GRIDS=890,8010,72090 ST_SRID=2');

This is a custom index type from a 3rd-partyvendor, and it Causes Chronic Performance Degrading during high -卷更新/插入/删除操作。

关于如何解决此错误有什么建议吗?顺便说一句,此错误仅发生在 PL/SQL 块内。

编辑:以下是完整的过程:

procedure disable_indexes (
  tbl_name in varchar2
) as
  stmt varchar2(200);
  cursor curs(v_tbl_name in varchar2) is
    select 'alter index ' || index_name || ' unusable;' as ddl_stmt
    from user_indexes
    where upper(table_owner) = upper(user)
    and upper(table_name) = upper(v_tbl_name)
    and ityp_name in ('CTXCAT', 'ST_SPATIAL_INDEX');
begin
  for r_curs in curs(tbl_name) loop
    dbms_output.put_line(r_curs.ddl_stmt);
    execute immediate r_curs.ddl_stmt;
  end loop;
end;

I've written a PL/SQL procedure that would benefit if indexes were first disabled, then rebuilt upon completion. An existing thread suggests this approach:

alter session set skip_unusable_indexes = true;

alter index your_index unusable;

[do import]

alter index your_index rebuild;

However, I get the following error on the first alter index statement:

SQL Error: ORA-14048: a partition maintenance operation may not be combined with other operations
ORA-06512: [...]
14048. 00000 -  "a partition maintenance operation may not be combined with other operations"
*Cause:    ALTER TABLE or ALTER INDEX statement attempted to combine
           a partition maintenance operation (e.g. MOVE PARTITION) with some
           other operation (e.g. ADD PARTITION or PCTFREE which is illegal
*Action:   Ensure that a partition maintenance operation is the sole
           operation specified in ALTER TABLE or ALTER INDEX statement;
           operations other than those dealing with partitions,
           default attributes of partitioned tables/indices or
           specifying that a table be renamed (ALTER TABLE RENAME) may be
           combined at will

The problem index is defined so:

CREATE INDEX A11_IX1 ON STREETS ("SHAPE")
  INDEXTYPE IS "SDE"."ST_SPATIAL_INDEX" PARAMETERS
  ('ST_GRIDS=890,8010,72090 ST_SRID=2');

This is a custom index type from a 3rd-party vendor, and it causes chronic performance degradation during high-volume update/insert/delete operations.

Any suggestions on how to work around this error? By the way, this error only occurs within a PL/SQL block.

Edit: Here is the procedure in its entirety:

procedure disable_indexes (
  tbl_name in varchar2
) as
  stmt varchar2(200);
  cursor curs(v_tbl_name in varchar2) is
    select 'alter index ' || index_name || ' unusable;' as ddl_stmt
    from user_indexes
    where upper(table_owner) = upper(user)
    and upper(table_name) = upper(v_tbl_name)
    and ityp_name in ('CTXCAT', 'ST_SPATIAL_INDEX');
begin
  for r_curs in curs(tbl_name) loop
    dbms_output.put_line(r_curs.ddl_stmt);
    execute immediate r_curs.ddl_stmt;
  end loop;
end;

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

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

发布评论

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

评论(2

温馨耳语 2024-09-08 08:36:51

如果这确实是您的代码而不是伪代码重写,请删除 stmt 变量中语句末尾的 ; (否则您将遇到 ORA-00911:执行期间无效字符

现在,如果您的进程手动工作,您应该能够使其与过程中的立即执行一起工作。确保这不是角色问题(请参阅 Tom Kyte 的文章< /a>),在手动执行命令之前发出SET ROLE NONE

If this is really your code and not a pseudo-code rewrite, remove the ; at the end of your statement in the stmt variable (otherwise you will run into ORA-00911: invalid character during execution)

Now if your process works manually, you should be able to make it work with execute immediate in a procedure. Make sure that this is not a role issue (see this article by Tom Kyte) by issuing SET ROLE NONE before executing the commands manually.

靑春怀旧 2024-09-08 08:36:51

您是否尝试过先执行 DROP INDEX,然后再重新创建它?

Have you tried to do a DROP INDEX before and then recreate it after?

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