在Oracle數據庫中,創(chuàng )建索引雖然比較簡(jiǎn)單。但是要合理的創(chuàng )建索引則比較困難了。筆者認為,在創(chuàng )建索引時(shí)要做到三個(gè)適當,即在適當的表上、適當的列上創(chuàng )建適當數量的索引。
在Oracle數據庫中,創(chuàng )建索引雖然比較簡(jiǎn)單。但是要合理的創(chuàng )建索引則比較困難了。筆者認為,在創(chuàng )建索引時(shí)要做到三個(gè)適當,即在適當的表上、適當的列上創(chuàng )建適當數量的索引。雖然這可以通過(guò)一句話(huà)來(lái)概括優(yōu)化的索引的基本準則,但是要做到這一點(diǎn)的話(huà),需要數據庫管理員做出很大的努力。具體的來(lái)說(shuō),要做到這個(gè)三個(gè)適當有如下幾個(gè)要求。
一、 根據表的大小來(lái)創(chuàng )建索引。
雖然給表創(chuàng )建索引,可以提高查詢(xún)的效率。但是數據庫管理員需要注意的是,索引也需要一定的開(kāi)銷(xiāo)的。為此并不是說(shuō)給所有的表都創(chuàng )建索引,那么就可以提高數據庫的性能。這個(gè)認識是錯誤的。恰恰相反,如果不管三七二十一,給所有的表都創(chuàng )建了索引,那么其反而會(huì )給數據庫的性能造成負面的影響。因為此時(shí)濫用索引的開(kāi)銷(xiāo)可能已經(jīng)遠遠大于由此帶來(lái)的性能方面的收益。所以筆者認為,數據庫管理員首先需要做到,為合適的表來(lái)建立索引,而不是為所有的表建立索引。
一般來(lái)說(shuō),不需要為比較小的表創(chuàng )建索引。如在一個(gè)ERP系統的數據庫中,department表用來(lái)存儲企業(yè)部門(mén)的信息。一般企業(yè)的部分也就十幾個(gè),最多不會(huì )超過(guò)一百個(gè)。這100條記錄對于人來(lái)說(shuō),可能算是比較多了。但是對于計算機來(lái)說(shuō),這給他塞塞牙縫都還不夠。所以,對類(lèi)似的小表沒(méi)有必要建立索引。因為即使建立了索引,其性能也不會(huì )得到很大的改善。相反索引建立的開(kāi)銷(xiāo),如維護成本等等,要比這個(gè)要大。也就是說(shuō),付出的要比得到的多,顯然違反常理。
另外,就是對于超大的表,也不一定要建立索引。有些表雖然比較大,記錄數量非常的多。但是此時(shí)為這個(gè)表建立索引并一定的合適。如系統中有一張表,其主要用來(lái)保存數據庫中的一些變更信息。往往這些信息只給數據庫管理員使用。此時(shí)為這張表建立索引的話(huà),反而不合適。因為這張表很少用到,只有在出問(wèn)題的時(shí)候才需要查看。其次其即使查看,需要查詢(xún)的紀錄也不會(huì )很多,可能就是最近一周的更新記錄等等。對于對于一些超大的表,建立索引有時(shí)候往往不能夠達到預計的效果。而且在打表上建立索引,其索引的開(kāi)銷(xiāo)要比普通的表大的多。那么到底是否給大表建立索引呢?筆者認為,主要是看兩個(gè)方面的內容。首先是需要關(guān)注一下,在這張大表中經(jīng)常需要查詢(xún)的記錄數量。一般來(lái)說(shuō),如果經(jīng)常需要查詢(xún)的數據不超過(guò)10%到15%的話(huà),那就沒(méi)有必要為其建立索引的必要。因為此時(shí)建立索引的開(kāi)銷(xiāo)可能要比性能的改善大的多。這個(gè)比例只是一個(gè)經(jīng)驗的數據。如果數據庫管理員需要得出一個(gè)比較精確的結論,那么就需要進(jìn)行測試分析。即數據庫管理員需要測試一下全表掃描的時(shí)間,看看其是否比建立索引后的查詢(xún)時(shí)間要長(cháng)或者短。如果是長(cháng)的話(huà),則說(shuō)明有建立索引的必要。但是如果沒(méi)有的話(huà),則說(shuō)明還是全表掃描速度來(lái)的快。此時(shí)也就沒(méi)有必要建立索引了。
總之,在考慮是否該為表建立索引時(shí),一般來(lái)說(shuō)小表沒(méi)有建立索引的必要。而對于打表的話(huà),則需要進(jìn)行實(shí)際情況實(shí)際分析。簡(jiǎn)單一點(diǎn)的,可以根據大致的比率來(lái)確定。如果要精確一點(diǎn)的,則可以進(jìn)行全表掃描性能分析,以判斷建立索引后是否真的如預期那樣改善了數據庫性能。
二、 根據列的特征來(lái)創(chuàng )建索引。
列的特點(diǎn)不同,索引創(chuàng )建的效果也不同。數據庫管理員需要了解為哪些列創(chuàng )建索引可以起到事倍功半的效果。同時(shí)也需要了解為哪些列創(chuàng )建索引反而起到的是事倍功半的效果。這有利于他們了解到底給為怎么樣的字段建立索引。
根據筆者的經(jīng)驗,往往為如下特征的列創(chuàng )建索引能夠起到比較明顯的效果。如對于一些重復內容比較少的列,特別是對于那些定義了唯一約束的列。在這些列上建立索引,往往可以起到非常不錯的效果。如對于一些null值的列與非Null值的列混合情況下,如果用戶(hù)需要經(jīng)常查詢(xún)所有的非Null值記錄的列,則最好為其設置索引。如果經(jīng)常需要多表連接查詢(xún),在用與連接的列上設置索引可以達到事半功倍的效果。
可見(jiàn),索引設置的是否恰當,不僅跟數據庫設計架構有關(guān),而且還跟企業(yè)的經(jīng)濟業(yè)務(wù)相關(guān)。為此,對于一些套裝軟件,雖然一開(kāi)始數據庫管理員已經(jīng)做了索引的優(yōu)化工作。但是隨著(zhù)后來(lái)經(jīng)濟數據的增加,這個(gè)索引的效果會(huì )越來(lái)越打折扣。這主要是因為記錄的表化影響到了索引優(yōu)化的效果。所以筆者建議各位數據庫管理員,即使采用的是大牌軟件公司的套裝軟件,也需要隔一段時(shí)間,如一年,對數據庫的索引進(jìn)行優(yōu)化。該去掉的去掉,該調整的調整,以提高數據庫的性能。
如在數據庫中有一張表是用來(lái)保存用戶(hù)信息的。其中有個(gè)字段身份證號碼,這是一個(gè)唯一的字段。在數據庫設計時(shí),給這個(gè)字段創(chuàng )建了索引。但是當這個(gè)數據庫投入使用之后,用戶(hù)不怎么輸入用戶(hù)的身份證號碼。而且平時(shí)也基本不按這個(gè)號碼來(lái)進(jìn)行查詢(xún)。當記錄月來(lái)月多時(shí),這個(gè)身份證號碼上的索引字段不但不能夠改善數據庫的查詢(xún)性能,反而成了雞肋。對于這些有很多NULL值的列,而且不會(huì )經(jīng)常查詢(xún)所有的非NULL值記錄的列,數據庫管理員要下決心,即使清除這些列上的索引。
所以說(shuō)索引的優(yōu)化與調整是一個(gè)動(dòng)態(tài)的過(guò)程,并不是說(shuō)數據庫設計好之后就不需要經(jīng)過(guò)調整。數據庫管理員往往需要根據記錄的變化情況,來(lái)進(jìn)行適當的變更。以提高索引的效果。
在Oracle數據庫中,創(chuàng )建索引雖然比較簡(jiǎn)單。但是要合理的創(chuàng )建索引則比較困難了。筆者認為,在創(chuàng )建索引時(shí)要做到三個(gè)適當,即在適當的表上、適當的列上創(chuàng )建適當數量的索引。
三、 在一個(gè)表上創(chuàng )建多少索引合適?
雖然說(shuō),在表上創(chuàng )建索引的數量沒(méi)有限制,但是決不是越多越好。也就是說(shuō),在創(chuàng )建索引這項事情上,1 1〉2往往不成立。有時(shí)候,創(chuàng )建索引越多,其可能會(huì )得到適得其反的效果。那么在一個(gè)表上,到底給創(chuàng )建多少索引合適呢?這個(gè)沒(méi)有一個(gè)明確的標準。而是需要數據庫管理員根據實(shí)際的用途以及數據庫中記錄的情況,來(lái)進(jìn)行判斷。
通常來(lái)說(shuō),表的索引越多,其查詢(xún)的速度也就越快。但是,表的更新速度則會(huì )降低。這主要是因為表的更新(如往表中插入一條記錄)速度,反而隨著(zhù)索引的增加而增加。這主要是因為,在更新記錄的同時(shí)需要更新相關(guān)的索引信息。為此,到底在表中創(chuàng )建多少索引合適,就需要在這個(gè)更新速度與查詢(xún)速度之間取得一個(gè)均衡點(diǎn)。如對于一些數據倉庫或者決策型數據庫系統,其主要用來(lái)進(jìn)行查詢(xún)。相關(guān)的記錄往往是在數據庫初始化的時(shí)候倒入。此時(shí),設置的索引多一點(diǎn),可以提高數據庫的查詢(xún)性能。同時(shí)因為記錄不怎么更新,所以索引比較多的情況下,也不會(huì )影響到更新的速度。即使在起初的時(shí)候需要導入大量的數據,此時(shí)也可以先將索引禁用掉。等到數據導入完畢后,再啟用索引??梢酝ㄟ^(guò)這種方式來(lái)減少索引對數據更新的影響。相反,如果那些表中經(jīng)常需要更新記錄,如一些事務(wù)型的應用系統,數據更新操作是家常便飯的事情。此時(shí)如果在一張表中建立過(guò)多的索引,則會(huì )影響到更新的速度。由于更新操作比較頻繁,所以對其的負面影響,要比查詢(xún)效率提升要大的多。此時(shí)就需要限制索引的數量,只在一些必要的字段上建立索引。
筆者在平時(shí)數據庫優(yōu)化時(shí),往往會(huì )根據這些表的用途來(lái)為列設置索引??梢圆樵?xún)相關(guān)的動(dòng)態(tài)視圖,看看對于這張表的操作,是更新操作(包括更新、刪除、插入等等)占的比例大,還是查詢(xún)操作占的比例大。當過(guò)多的索引已經(jīng)影響到更新操作的速度時(shí),則數據庫管理員就需要先禁用某些索引,以提高數據庫的性能。
總之,在適當的表、適當的列上建立適當的索引。這一句話(huà)包含的意思有很多,以上內容只是一部分內容。俗話(huà)說(shuō),師傅領(lǐng)進(jìn)門(mén),修行靠自身。筆者在這里指能夠點(diǎn)到為止。一些具體的索引優(yōu)化內容還是需要各位讀者在日常工作中去體會(huì )與總結。