oracle索引整理

From:http://liusuper.iteye.com/blog/219013

 

一、oracle的索引陷阱
    一個表中有幾百萬條數據,對某個字段加了索引,但是查詢時性能並沒有什麼提高,這主要可能是oracle的索引限製造成的。oracle的索引有一些索引限制,在這些索引限制發生的情況下,即使已經加了索引,oracle還是會執行一次全表掃描,查詢的性能不會比不加索引有所提高,反而可能由於數據庫維護索引的系統開銷造成性能更差。
下面是一些常見的索引限制問題。
 
1、使用不等於操作符(<>,!=)
    下面這種情況,即使在列dept_id有一個索引,查詢語句仍然執行一次全表掃描
select * from dept where staff_num <> 1000;
    但是開發中的確需要這樣的查詢,難道沒有解決問題的辦法了嗎?
    有!
    通過把用or語法代替不等號進行查詢,就可以使用索引,以避免全表掃描;上面的語句改成下面這樣的,就可以使用索引了。
select * from dept where staff_num < 1000 or dept_id > 1000;
 
2、使用is null或is not null
    使用is null或is not null也會限制索引的使用,因爲數據庫並沒有定義null值。如果被索引的列中有很多null,就不會使用這個索引(除非索引是一個位圖索引,關於位圖索引,會在以後的blog文章裏做詳細解釋)。在sql語句中使用null
會造成很多麻煩。
解決這個問題的辦法是:建表時把需要索引的列定義爲非空(not null)。
 
3、使用函數
    如果沒有使用基於函數的索引,那麼where子句中對存在索引的列使用函數時,會使優化器忽略掉這些索引。下面的查詢就不會使用索引:
select * from staff where trunc(birthdate) = '01-MAY-82';
    但是把函數應用在條件上,索引是可以生效的,把上面的語句改成下面的語句,就可以通過索引進行查找。
select * from staff where birthdate < (to_date('01-MAY-82')+0.9999);
 
4、比較不匹配的數據類型
    比較不匹配的數據類型也是難於發現的性能問題之一。
    下面的例子中,dept_id是一個varchar2型的字段,在這個字段上有索引,但是下面的語句會執行全表掃描。
select * from dept where dept_id = 900198;
    這是因爲oracle會自動把where子句轉換成to_number(dept_id) = 900198,就是3所說的情況,這樣就限制了索引的使用。把SQL語句改爲如下形式就可以使用索引。
select * from dept where dept_id = '900198';
 
二,各種索引使用場合及建議
(1)B*Tree索引
常規索引,多用於oltp系統,快速定位行,應建立高cardinality列(即列的唯一值除以行數爲一個很大的值,存在很少的相同值)。
create index indexname on tablename(columnname[columnname...])
(2)反向索引
    B*Tree的衍生產物,應用於特殊場合,在ops環境加序列增加的列上建立,不適合做區域掃描。
create index indexname on tablename(columnname[columnname...]) reverse
(3)降序索引
    B*Tree的衍生產物,應用於有降序排序的搜索語句中,索引中存儲了降序排列的索引碼,提供了快速的降序搜素。
create index indexname on tablename(columnname DESC[columnname...])
(4)位圖索引
    位圖方式管理的索引,適用於OLAP(在線分析)和DSS(決策處理)系統,應建立於低cardinality列,適合集中讀取,不適合插入和修改,提供比B*Tree索引更節省的空間。
create bitmap index indexname on tablename(columnname[columnname...])
    在實際應用中,如果某個字段的值需要頻繁更新,那麼就不適合在它上面創建位圖索引。在位圖索引中,如果你更新或插入其中一條數值爲N的記錄,那麼相應表中數值爲N的記錄(可能成百上千條)全部被Oracle鎖定,這就意味着其它用戶不能同時更新這些數值爲N的記錄,其他用戶必須要等待第一個用戶提交後,才能獲得鎖,更新或插入數據,bitmap index它主要用戶決策支持系統或靜態數據。
(5)函數索引
    B*Tree的衍生產物,應用於查詢語句條件列上包含函數的情況,索引中存儲了經過函數計算的索引碼值。可以在不修改應用程序的基礎上能提高查詢效率。
 
三、索引創建策略
1、導入數據後再創建索引
2、不需要爲很小的表創建索引
3、對於取值範圍很小的字段(不如性別字段)應當建立位圖索引
4、限制表中索引的數目
5、爲索引設置合適的PCTFREE值
6、存儲索引的表空間最好單獨設定
 
唯一索引和不唯一索引都只是針對B樹索引而言。
Oracle最多允許包含32個字段的複合索引。
由此估計出一個查詢如果使用某個索引會需要讀入的數據塊塊數。
需要讀入的數據塊越多,則cost越大,Oracle也就越有可能不選擇使用index。
 
四、小結
能用唯一索引,一定用唯一索引
能加非空,就加非空約束
一定要統計表的信息,索引的信息,柱狀圖的信息
聯合索引的順序不同,影響索引的選擇,儘量將值少的放在前面
只有做到以上四點,數據庫纔會正確的選擇執行計劃
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章