bro*_*ng0 3 sql oracle indexing unique-constraint oracle11g
在史蒂夫·奥赫恩 (Steve O'Hearn) 的“SQL 认证专家考试指南”中,我找到了这一段:
在创建复合索引以及调用同一索引的多个约束时,在极少数情况下,需要特殊语法。例如,如果我们决定在 INVOICES 表中的两个列上创建一个复合索引,我们可以使用以下语法:
CREATE TABLE invoices
(
invoice_id NUMBER(11),
invoice_date DATE,
CONSTRAINT un_invoices_invoice_id UNIQUE (invoice_id, invoice_date)
USING INDEX (CREATE INDEX ix_invoices
ON invoices(invoice_id, invoice_date)),
CONSTRAINT un_invoices_invoice_date UNIQUE (invoice_date, invoice_id)
USING INDEX ix_invoices
);
Run Code Online (Sandbox Code Playgroud)
这是我的问题:
创建两个唯一约束仅更改声明中的列顺序有什么意义?
我们创建了一个多列索引:“invoice_id”作为第一列,“invoice_date”作为第二列。但是让我们假设我们真的经常运行与“invoice_date”本身相关的查询,而没有“invoice_id”的参与。在“invoice_date”上创建第二个单列索引是个好主意吗?我知道:
由于 Oracle 支持多列索引,因此很容易意外创建“重复”索引,这些索引会增加 DML 的开销并且无助于加快 SQL 执行速度。 [来源]
我也知道:
由于跳过扫描引用复合索引中任何列的 WHERE 子句,可能会在处理过程中调用索引。[史蒂夫·奥赫恩]
但我也知道:
这不如简单的单列索引那么有益,它的好处因第一列中值的唯一性而异。[史蒂夫·奥赫恩]
因此,假设我们很少在此表上使用 DML 命令,并且假设我们与 SELECT 的 WHERE 子句中的两列相关,就像分别与“index_date”或“index_id”相关。在某些情况下,创建两个索引是否合理?一,多列索引,在(index_id,index_date)上,第二,单列索引,在(index_date)?
你的问题是:
在某些情况下,创建两个索引是否合理?一,多列索引,在(index_id,index_date)上,第二,单列索引,在(index_date)上?
答案是“是”。第一个索引将用于满足以下条件的查询:
index_id在where子句中过滤index_id和子句index_date中进行过滤whereindex_id子句中的过滤where和排序依据index_date在这些情况下不会使用第二个索引。它将用于:
index_date在where子句中过滤在这种情况下不会使用第一个索引。
索引中列的顺序很重要。它们是从左到右使用的。所以,这两个索引很有用。然而,单独使用第三个索引index_id是没有用的,因为第一个索引已经处理了使用该索引的相同情况。
你问
“创建两个唯一约束仅更改声明中的列顺序有什么意义?”
没有任何意义。复合约束中的列顺序没有任何区别:
SQL> select * from t23
2 /
COL1 COL
---------- ---
1 WTF
SQL> create index t23_i on t23(col1, col2);
Index created.
SQL> alter table t23 add constraint t23_uk unique (col1 , col2) using index t23_i
2 /
Table altered.
SQL> insert into t23 values (1, 'WTF')
2 /
insert into t23 values (1, 'WTF')
*
ERROR at line 1:
ORA-00001: unique constraint (APC.T23_UK) violated
SQL> alter table t23 drop constraint t23_uk
2 /
Table altered.
SQL> alter table t23 add constraint t23_uk unique (col2, col1) using index t23_i
2 /
Table altered.
SQL> insert into t23 values (1, 'WTF')
2 /
insert into t23 values (1, 'WTF')
*
ERROR at line 1:
ORA-00001: unique constraint (APC.T23_UK) violated
SQL>
Run Code Online (Sandbox Code Playgroud)
这就是考试填鸭式的问题:他们经常只说一些东西,而没有提供解释或上下文。
你还问:
“在 上创建第二个单列索引是个好主意
invoice_date吗?”
在不知道数据的情况下很难判断,但我希望日期列的选择性低于 ID 列(尤其是在时间元素被截断的情况下),因此通常我希望索引能够以(invoice_date, invoice_id)任何方式构建。这可能允许我们使用索引压缩。
跳过扫描并不像史蒂夫所说的那样工作:它首先探测索引的前沿,但前提是复合索引中的第二列在 WHERE 子句中被引用。优化器可能会选择完全快速索引扫描来搜索第三列或更低的列。如果前沿有太多不同的值,它也不会选择跳过扫描路径:另一个有选择地以低列领先的好理由。
所以,这并不能完全回答你的问题,但我认为它确实传达了一个重要的观点:没有通用的规则来管理为性能创建索引。我们需要了解数据的概况——它的值分布和数量——以及将使用该表的最重要的查询。
| 归档时间: |
|
| 查看次数: |
2680 次 |
| 最近记录: |