Oracle提供了大量索引選項
知道在給定條件下使用哪個選項對於一個應用程序的性能來說非常重要
一個錯誤的選擇可能會引發死鎖
並導致數據庫性能急劇下降或進程終止
而如果做出正確的選擇
則可以合理使用資源
使那些已經運行了幾個小時甚至幾天的進程在幾分鐘得以完成
這樣會使您立刻成為一位英雄
這篇文章就將簡單的討論每個索引選項
主要有以下內容
[
] 基本的索引概念
查詢DBA_INDEXES視圖可得到表中所有索引的列表
注意只能通過USER_INDEXES的方法來檢索模式(schema)的索引
訪問USER_IND_COLUMNS視圖可得到一個給定表中被索引的特定列
[
] 組合索引
當某個索引包含有多個已索引的列時
稱這個索引為組合(concatented)索引
在 Oracle
i引入跳躍式掃描的索引訪問方法之前
查詢只能在有限條件下使用該索引
比如
表emp有一個組合索引鍵
該索引包含了empno
ename和deptno
在Oracle
i之前除非在where之句中對第一列(empno)指定一個值
否則就不能使用這個索引鍵進行一次范圍掃描
特別注意
在Oracle
i之前
只有在使用到索引的前導索引時才可以使用組合索引!
[
] ORACLE ROWID
通過每個行的ROWID
索引Oracle提供了訪問單行數據的能力
ROWID其實就是直接指向單獨行的線路圖
如果想檢查重復值或是其他對ROWID本身的引用
可以在任何表中使用和指定rowid列
[
] 限制索引
限制索引是一些沒有經驗的開發人員經常犯的錯誤之一
在SQL中有很多陷阱會使一些索引無法使用
下面討論一些常見的問題
使用不等於操作符(<>!=) 下面的查詢即使在cust_rating列有一個索引
查詢語句仍然執行一次全表掃描
select cust_Id
cust_name
from customers
where cust_rating <>
aa
;
把上面的語句改成如下的查詢語句
這樣
在采用基於規則的優化器而不是基於代價的優化器(更智能)時
將會使用索引
select cust_Id
cust_name
from customers
where cust_rating <
aa
or cust_rating >
aa
;
特別注意
通過把不等於操作符改成OR條件
就可以使用索引
以避免全表掃描
使用IS NULL 或IS NOT NULL 使用IS NULL 或IS NOT NULL同樣會限制索引的使用
因為NULL值並沒有被定義
在SQL語句中使用NULL會有很多的麻煩
因此建議開 發人員在建表時
把需要索引的列設成NOT NULL
如果被索引的列在某些行中存在NULL值
就不會使用這個索引(除非索引是一個位圖索 引
關於位圖索引在稍後在詳細討論)
使用函數 如果不使用基於函數的索引
那麼在SQL語句的WHERE子句中對存在索引的列使用函數時
會使優化器忽略掉這些索引
下面的查詢不會使用索引(只要它不是基於函數的索引)
select empno
ename
deptno
from emp
where trunc(hiredate)=
MAY
;
把上面的語句改成下面的語句
這樣就可以通過索引進行查找
select empno
ename
deptno
from emp
where hiredate<(to_date(
MAY
)+
);
比較不匹配的數據類型 比較不匹配的數據類型也是比較難於發現的性能問題之一
注意下面查詢的例子
account_number是一個VARCHAR
類型
在account_number字段上有索引
下面的語句將執行全表掃描
select bank_name
address
city
state
zip
from banks
where account_number =
;
Oracle可以自動把where子句變成to_number(account_number)=
這樣就限制了索引的使用
改成下面的查詢就可以使用索引
select bank_name
address
city
state
zip
from banks
where account_number =
;
特別注意
不匹配的數據類型之間比較會讓Oracle自動限制索引的使用
即便對這個查詢執行Explain Plan也不能讓您明白為什麼做了一 次
全表掃描
[
] 選擇性
使用USER_INDEXES視圖
該視圖中顯示了一個distinct_keys列
比較一下唯一鍵的數量和表中的行數
就可以判斷索引的選擇性
選擇性越高
索引返回的數據就越少
[
] 群集因子(Clustering Factor)
Clustering Factor位於USER_INDEXES視圖中
該列反映了數據相對於已索引的列是否顯得有序
如果Clustering Factor列的值接近於索引中的樹葉塊(leaf block)的數目
表中的數據就越有序
如果它的值接近於表中的行數
則表中的數據就不是很有序
[
] 二元高度(Binary height)
索引的二元高度對把ROWID返回給用戶進程時所要求的I/O量起到關鍵作用
在對一個索引進行分析後
可以通過查詢DBA_INDEXES的B
level列查看它的二元高度
二元高度主要隨著表的大小以及被索引的列中值的范圍的狹窄程度而變化
索引上如果有大量被刪除的行
它的二元高度也會增加
更新索引列也類似於刪除操作
因為它增加了已刪除鍵的數目
重建索引可能會降低二元高度
[
] 快速全局掃描
在Oracle
後就可以使用快速全局掃描(Fast Full Scan)這個選項
這個選項允許Oracle執行一個全局索引掃描操作
快速全局掃描讀取B
樹索引上所有樹葉塊
初始化文件中的DB_FILE_MULTIBLOCK_READ_COUNT參數可以控制同時被讀取的塊的數目
[
] 跳躍式掃描
從Oracle
i開始
索引跳躍式掃描特性可以允許優化器使用組合索引
即便索引的前導列沒有出現在WHERE子句中
索引跳躍式掃描比全索引掃描要快的多
下面的程序清單顯示出性能的差別
create index skip
on emp
(job
empno);
index created
select count(*)
from emp
where empno=
;
Elapsed:
:
:
Execution Plan
SELECT STATEMENT Optimizer=CHOOSE(Cost=
Card=
Bytes=
)
SORT(AGGREGATE)
INDEX(FAST FULL SCAN) OF
SKIP
(NON
UNIQUE)
Statistics
consistent gets
physical reads
select /*+ index(emp
skip
)*/ count(*)
from emp
where empno=
;
Elapsed:
:
:
Execution Plan
SELECT STATEMENT Optimizer=CHOOSE(Cost=
Card=
Bytes=
)
SORT(AGGREGATE)
INDEX(SKIP SCAN) OF
SKIP
(NON
UNIQUE)
Statistics
consistent gets
physical reads
[
] 索引的類型
B
樹索引
位圖索引
HASH索引
索引編排表
反轉鍵索引
基於函數的索引
分區索引
本地和全局索引
From:http://tw.wingwit.com/Article/program/Oracle/201311/16507.html