Oracle:获取使用CREATE [UNIQUE] INDEX 明确创建的索引。

huangapple go评论64阅读模式
英文:

Oracle: Get the indexes created explicitely with CREATE [UNIQUE] INDEX

问题

使用Oracle(19.3和21.3),我们希望找到通过实际的CREATE [UNIQUE] INDEX指令创建的索引,并排除那些由约束自动创建的索引,比如PRIMARY KEY和UNIQUE。

现有的系统视图似乎不太容易实现这一点,因为我们需要执行相当复杂的查询来排除在ALL_CONSTRAINTS中引用的索引。

不好的消息是,这个查询执行起来需要一些时间(在19.3下约6秒,在21.3下约15秒!)

需要注意的是:根据我的理解,ALL_INDEXES.GENERATED列指示索引的名称是否是由Oracle自动生成的,而不是索引本身是否由表约束自动创建。

我们知道dbms_metadata.GET_DDL(),但它返回各种类型的索引...

有什么线索吗?

谢谢!
Seb

以下是测试SQL:

CREATE TABLE tab3 (
    id INTEGER NOT NULL PRIMARY KEY,
    name VARCHAR(50) UNIQUE
);

CREATE TABLE tab1 (
    id INTEGER NOT NULL PRIMARY KEY,
    name VARCHAR(50) UNIQUE,
    crea DATE,
    ratio DECIMAL(10,2),
    FOREIGN KEY (name) REFERENCES tab3 (name)
);

CREATE INDEX ix1_tab1 ON tab1 ( crea );

CREATE TABLE tab2 (
    id INTEGER NOT NULL,
    name VARCHAR(50),
    CONSTRAINT pktab2 PRIMARY KEY (id),
    CONSTRAINT uktab2_1 UNIQUE (name),
    CONSTRAINT fktab2_1 FOREIGN KEY (name) REFERENCES tab3 (name)
);

SET LINESIZE 400
SET PAGESIZE 400

COLUMN OWNER format a20
COLUMN TABLE_NAME format a20
COLUMN COLUMN_NAME format a20
COLUMN INDEX_NAME format a20
COLUMN CONSTRAINT_NAME format a20

SELECT c.OWNER, c.TABLE_NAME, c.CONSTRAINT_NAME, c.CONSTRAINT_TYPE T, c.INDEX_NAME
    FROM ALL_CONSTRAINTS c
         WHERE UPPER(c.OWNER)=UPPER(USER)
           AND c.CONSTRAINT_TYPE IN ('C','P','U','R')
           AND c.CONSTRAINT_NAME NOT LIKE 'BIN$%'
 ORDER BY c.OWNER, c.TABLE_NAME, c.CONSTRAINT_NAME
;

SELECT i.OWNER, i.TABLE_NAME, i.INDEX_NAME, ic.COLUMN_NAME, i.UNIQUENESS, i.GENERATED
    FROM ALL_INDEXES i
      INNER JOIN ALL_IND_COLUMNS ic
            ON (i.TABLE_NAME = ic.TABLE_NAME
                AND i.INDEX_NAME = ic.INDEX_NAME
                AND i.TABLE_OWNER = ic.TABLE_OWNER)
   WHERE i.OWNER <> 'SYS' AND i.OWNER <> 'SYSTEM'
     AND UPPER(i.OWNER)=UPPER(USER)
 ORDER BY i.TABLE_NAME, i.INDEX_NAME, ic.COLUMN_POSITION
;

SELECT i.OWNER, i.TABLE_NAME, i.INDEX_NAME, ic.COLUMN_NAME, i.UNIQUENESS
    FROM ALL_INDEXES i
      INNER JOIN ALL_IND_COLUMNS ic
            ON (i.TABLE_NAME = ic.TABLE_NAME
                AND i.INDEX_NAME = ic.INDEX_NAME
                AND i.TABLE_OWNER = ic.TABLE_OWNER)
   WHERE i.OWNER <> 'SYS' AND i.OWNER <> 'SYSTEM'
     AND UPPER(i.OWNER)=UPPER(USER)
     AND i.INDEX_NAME NOT IN (
         SELECT c.INDEX_NAME
           FROM ALL_CONSTRAINTS c
          WHERE UPPER(c.OWNER)=UPPER(USER)
            AND c.CONSTRAINT_TYPE IN ('P','U')
            AND c.CONSTRAINT_NAME NOT LIKE 'BIN$%'
         )
 ORDER BY i.TABLE_NAME, i.INDEX_NAME, ic.COLUMN_POSITION
英文:

Using Oracle (19.3 and 21.3), we would like to find the indexes created with a real CREATE [UNIQUE] INDEX instruction, and exclude those that are automatically created by constraints like PRIMARY KEY and UNIQUE.

Seems not to be so easy with existing system views, as we have to make a quite complex query to exclude indexes referenced in ALL_CONSTRAINTS.

The bad news is that this query takes a while to execute (~6s with 19.3 et ~15s with 21.3!)

Take care: From my understanding, ALL_INDEXES.GENERATED column indicates if the index name was automatically generated by Oracle, not the fact that the index itself was automatically created by a table constraint.

We know about dbms_metadata.GET_DDL() but that one returns all kind of indexes...

Any clue?

Thanks!
Seb

Here the test SQL:

CREATE TABLE tab3 (
id INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(50) UNIQUE
);
CREATE TABLE tab1 (
id INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(50) UNIQUE,
crea DATE,
ratio DECIMAL(10,2),
FOREIGN KEY (name) REFERENCES tab3 (name)
);
CREATE INDEX ix1_tab1 ON tab1 ( crea );
CREATE TABLE tab2 (
id INTEGER NOT NULL,
name VARCHAR(50),
CONSTRAINT pktab2 PRIMARY KEY (id),
CONSTRAINT uktab2_1 UNIQUE (name),
CONSTRAINT fktab2_1 FOREIGN KEY (name) REFERENCES tab3 (name)
);
SET LINESIZE 400
SET PAGESIZE 400
COLUMN OWNER format a20
COLUMN TABLE_NAME format a20
COLUMN COLUMN_NAME format a20
COLUMN INDEX_NAME format a20
COLUMN CONSTRAINT_NAME format a20
SELECT c.OWNER, c.TABLE_NAME, c.CONSTRAINT_NAME, c.CONSTRAINT_TYPE T, c.INDEX_NAME
FROM ALL_CONSTRAINTS c
WHERE UPPER(c.OWNER)=UPPER(USER)
AND c.CONSTRAINT_TYPE IN (&#39;C&#39;,&#39;P&#39;,&#39;U&#39;,&#39;R&#39;)
AND c.CONSTRAINT_NAME NOT LIKE &#39;BIN$%&#39;
ORDER BY c.OWNER, c.TABLE_NAME, c.CONSTRAINT_NAME
;
SELECT i.OWNER, i.TABLE_NAME, i.INDEX_NAME, ic.COLUMN_NAME, i.UNIQUENESS, i.GENERATED
FROM ALL_INDEXES i
INNER JOIN ALL_IND_COLUMNS ic
ON (i.TABLE_NAME = ic.TABLE_NAME
AND i.INDEX_NAME = ic.INDEX_NAME
AND i.TABLE_OWNER = ic.TABLE_OWNER)
WHERE i.OWNER &lt;&gt; &#39;SYS&#39; AND i.OWNER &lt;&gt; &#39;SYSTEM&#39;
AND UPPER(i.OWNER)=UPPER(USER)
ORDER BY i.TABLE_NAME, i.INDEX_NAME, ic.COLUMN_POSITION
;
SELECT i.OWNER, i.TABLE_NAME, i.INDEX_NAME, ic.COLUMN_NAME, i.UNIQUENESS
FROM ALL_INDEXES i
INNER JOIN ALL_IND_COLUMNS ic
ON (i.TABLE_NAME = ic.TABLE_NAME
AND i.INDEX_NAME = ic.INDEX_NAME
AND i.TABLE_OWNER = ic.TABLE_OWNER)
WHERE i.OWNER &lt;&gt; &#39;SYS&#39; AND i.OWNER &lt;&gt; &#39;SYSTEM&#39;
AND UPPER(i.OWNER)=UPPER(USER)
AND i.INDEX_NAME NOT IN (
SELECT c.INDEX_NAME
FROM ALL_CONSTRAINTS c
WHERE UPPER(c.OWNER)=UPPER(USER)
AND c.CONSTRAINT_TYPE IN (&#39;P&#39;,&#39;U&#39;)
AND c.CONSTRAINT_NAME NOT LIKE &#39;BIN$%&#39;
)
ORDER BY i.TABLE_NAME, i.INDEX_NAME, ic.COLUMN_POSITION

答案1

得分: 4

使用*_indexes视图中的constraint_index列。使用上面的DDL语句:

从 user_indexes 表中选择 index_name 和 constraint_index
其中 table_name 类似于 'TAB_';
INDEX_NAME      CONSTRAINT_INDEX    
SYS_C0044774    是                  
SYS_C0044775    是                  
IX1_TAB1        否                  
PKTAB2          是                  
UKTAB2_1        是                  
SYS_C0044771    是                  
SYS_C0044772    是  
英文:

Use the constraint_index column of the *_indexes views. Using the DDL above:

select index_name, constraint_index 
from   user_indexes
where  table_name like &#39;TAB_&#39;;
INDEX_NAME      CONSTRAINT_INDEX    
SYS_C0044774    YES                 
SYS_C0044775    YES                 
IX1_TAB1        NO                  
PKTAB2          YES                 
UKTAB2_1        YES                 
SYS_C0044771    YES                 
SYS_C0044772    YES  

huangapple
  • 本文由 发表于 2023年3月3日 19:05:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75626276.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定