IT貓撲網(wǎng):您身邊最放心的安全下載站! 最新更新|軟件分類(lèi)|軟件專(zhuān)題|手機(jī)版|論壇轉(zhuǎn)貼|軟件發(fā)布

您當(dāng)前所在位置: 首頁(yè)數(shù)據(jù)庫(kù)Oracle → Oracle索引使用規(guī)則

Oracle索引使用規(guī)則

時(shí)間:2015-06-28 00:00:00 來(lái)源:IT貓撲網(wǎng) 作者:網(wǎng)管聯(lián)盟 我要評(píng)論(0)

  邏輯上:

  Single column 單行索引

  Concatenated 多行索引

  Unique 唯一索引

  NonUnique 非唯一索引

  Function-based函數(shù)索引

  Domain 域索引

  物理上:

  Partitioned 分區(qū)索引

  NonPartitioned 非分區(qū)索引

  B-tree:

  Normal 正常型B樹(shù)

  Rever Key 反轉(zhuǎn)型B樹(shù)

  Bitmap 位圖索引

  索引結(jié)構(gòu):

  B-tree:

  適合與大量的增、刪、改(OLTP);

  不能用包含OR操作符的查詢(xún);

  適合高基數(shù)的列(唯一值多)

  典型的樹(shù)狀結(jié)構(gòu);

  每個(gè)結(jié)點(diǎn)都是數(shù)據(jù)塊;

  大多都是物理上一層、兩層或三層不定,邏輯上三層;

  葉子塊數(shù)據(jù)是排序的,從左向右遞增;

  在分支塊和根塊中放的是索引的范圍;

  Bitmap:

  適合與決策支持系統(tǒng);

  做UPDATE代價(jià)非常高;

  非常適合OR操作符的查詢(xún);

  基數(shù)比較少的時(shí)候才能建位圖索引;

  樹(shù)型結(jié)構(gòu):

  索引頭

  開(kāi)始ROWID,結(jié)束ROWID(先列出索引的最大范圍)

  BITMAP

  每一個(gè)BIT對(duì)應(yīng)著一個(gè)ROWID,它的值是1還是0,如果是1,表示著B(niǎo)IT對(duì)應(yīng)的ROWID有值;

  B*tree索引的話(huà)通常在訪(fǎng)問(wèn)小數(shù)據(jù)量的情況下比較適用,比如你訪(fǎng)問(wèn)不超過(guò)表中數(shù)據(jù)的5%,當(dāng)然這只是個(gè)相對(duì)的比率,適用于一般的情況。bitmap的話(huà)在數(shù)據(jù)倉(cāng)庫(kù)中使用較多,用于低基數(shù)列,比如性別之類(lèi)重復(fù)值很多的字段,基數(shù)越小越好。

  B* 樹(shù)索引

  這些是我所說(shuō)的 " 傳統(tǒng) " 索引。到目前為止,這是 Oracle 和大多數(shù)其他數(shù)據(jù)庫(kù)中最常用的索引。 B* 樹(shù)的構(gòu)造類(lèi)似于二叉樹(shù),能根據(jù)鍵提供一行或一個(gè)行集的快速訪(fǎng)問(wèn),通常只需很少的讀操作就能找到正確的行。不過(guò),需要注意重要的一點(diǎn), " B* 樹(shù) " 中的 " B " 不代表二叉( binary ),而代表平衡( b alanced )。B* 樹(shù)索引并不是一顆二叉樹(shù),這一點(diǎn)在介紹如何在磁盤(pán)上物理地存儲(chǔ) B* 樹(shù)時(shí)就會(huì)了解到。 B* 樹(shù)索引有以下子類(lèi)型:

  索引組織表( index organized table ):索引組織表以 B* 樹(shù)結(jié)構(gòu)存儲(chǔ)。堆表的數(shù)據(jù)行是以一種無(wú)組織的方式存儲(chǔ)的(只要有可用的空間,就可以放數(shù)據(jù)),而 IOT 與之不同, IOT 中的數(shù)據(jù)要按主鍵的順序存儲(chǔ)和排序。對(duì)應(yīng)用來(lái)說(shuō), IOT 表現(xiàn)得與 " 常規(guī) " 表并無(wú)二致;需要使用 SQL 來(lái)正確地訪(fǎng)問(wèn) IOT 。 IOT 對(duì)信息獲取、空間系統(tǒng)和 OLAP 應(yīng)用最為有用。 IOT 在上一章已經(jīng)詳細(xì)地討論過(guò)。

  B*樹(shù)聚簇索引( B*tree cluster index )這些是傳統(tǒng) B* 樹(shù)索引的一個(gè)變體(只是稍有變化)。 B* 樹(shù)聚簇索引用于對(duì)聚簇鍵建立索引(見(jiàn)第 11. 章中 " 索引聚簇表 " 一節(jié)),所以這一章不再討論。在傳統(tǒng) B* 樹(shù)中 ,鍵都指向一行;而 B* 樹(shù)聚簇不同,一個(gè)聚簇鍵會(huì)指向一個(gè)塊,其中包含與這個(gè)聚簇鍵相關(guān)的多行。

  降序索引( descending index ):降序索引允許數(shù)據(jù)在索引結(jié)構(gòu)中按 " 從大到小 " 的順序(降序)排序,而不是按 " 從小到大 " 的順序(升序)排序。我們會(huì)解釋為什么降序索引很重要,并說(shuō)明降序索引如何工作。

  反向鍵索引( reverse key index ):這也是 B* 樹(shù)索引,只不過(guò)鍵中的字節(jié)會(huì) " 反轉(zhuǎn) " 。利用反向鍵索引,如果索引中填充的是遞增的值,索引條目在索引中可以得到更均勻的分布。例如,如果使用一個(gè)序列來(lái)生成主鍵,這個(gè)序列將生成諸如 987500 、 987501 、 987502 等值。這些值是順序的,所以倘若使用一 個(gè)傳統(tǒng)的 B* 樹(shù)索引,這些值就可能放在同一個(gè)右側(cè)塊上,這就加劇了對(duì)這一塊的競(jìng)爭(zhēng)。利用反向鍵, Oracl e則會(huì)邏輯地對(duì) 205789 、 105789 、 005789 等建立索引。 Oracle 將數(shù)據(jù)放在索引中之前,將先 把所存儲(chǔ)數(shù)據(jù)的字節(jié)反轉(zhuǎn),這樣原來(lái)可能在索引中相鄰放置的值在字節(jié)反轉(zhuǎn)之后就會(huì)相距很遠(yuǎn)。通過(guò)反轉(zhuǎn)字節(jié),對(duì)索引的插入就會(huì)分布到多個(gè)塊上。

#p#副標(biāo)題#e#

  位圖索引( bitmap index )

  在一顆 B* 樹(shù)中,通常索引條目和行之間存在一種一對(duì)一的關(guān)系:一個(gè) 索引條目就指向一行。而對(duì)于位圖索引,一個(gè)索引條目則使用一個(gè)位圖同時(shí)指向多行。位圖索引適用于高度重復(fù)而且通常只讀的數(shù)據(jù)(高度重復(fù)是指相對(duì)于表中的總行數(shù),數(shù)據(jù)只有很少的幾個(gè)不同值)??紤]在一 個(gè)有 100 萬(wàn)行的表中,每個(gè)列只有 3 個(gè)可取值: Y 、 N 和 NULL 。舉例來(lái)說(shuō),如果你需要頻繁地統(tǒng)計(jì)多少行有值Y ,這就很適合建立位圖索引。不過(guò)并不是說(shuō)如果這個(gè)表中某一列有 11.000 個(gè)不同的值就不能建立位圖索引,這一列當(dāng)然也可以建立 位圖索引。在一個(gè) OLTP 數(shù)據(jù)庫(kù)中,由于存在并發(fā)性相關(guān)的問(wèn)題,所以不能考慮使用位圖索引(后面我們就會(huì)討論這一點(diǎn))。注意,位圖索引要求使用 Oracle 企業(yè)版或個(gè)人版。

  位圖聯(lián)結(jié)索引( bitmap join index ):這為索引結(jié)構(gòu)(而不是表)中的數(shù)據(jù)提供了一種逆規(guī)范化的 方法。例如,請(qǐng)考慮簡(jiǎn)單的 EMP 和 DEPT 表。有人可能會(huì)問(wèn)這樣一個(gè)問(wèn)題: " 多少人在位于波士頓的部門(mén)工作 ?" EMP 有一個(gè)指向 DEPT 的外鍵,要想統(tǒng)計(jì) LOC 值為 Boston 的部門(mén)中的員工人數(shù),通常必須完成表聯(lián)結(jié),將 LOC 列聯(lián)結(jié)至 EMP 記錄來(lái)回答這個(gè)問(wèn)題。通過(guò)使用位圖聯(lián)結(jié)索引,則可以在 EMP 表上對(duì) LOC 列建立索引 。

  基于函數(shù)的索引( function-based index )

  這些就是 B* 樹(shù)索引或位圖索引,它將一個(gè)函數(shù)計(jì)算得到的結(jié)果存儲(chǔ)在行的列中,而不是存儲(chǔ)列數(shù)據(jù)本身??梢园鸦诤瘮?shù)的索引看作一個(gè)虛擬列(或派生列)上的索引,換句話(huà)說(shuō),這個(gè)列并不物理存儲(chǔ)在表中。基于函數(shù)的索引可以用于加快形如 SELECT * FROM T W HERE FUNCTION(DATABASE_COLUMN) = SAME_VALUE 這樣的查詢(xún),因?yàn)橹?FUNCTION(DATABASE_COLUMN) 已經(jīng)提前計(jì)算并存儲(chǔ)在索引中。

  應(yīng)用域索引( application domain index )

  應(yīng)用域索引是你自己構(gòu)建和存儲(chǔ)的索引,可能存儲(chǔ)在Oracle 中,也可能在 Oracle 之外。你要告訴優(yōu)化器索引的選擇性如何,以及執(zhí)行的開(kāi)銷(xiāo)有多大,優(yōu)化器則會(huì)根據(jù)你提供的信息來(lái)決定是否使用你的索引。 Oracle 文本索引就是應(yīng)用域索引的一個(gè)例子;你也可 以使用構(gòu)建 Oracle 文本索引所用的工具來(lái)建立自己的索引。需要指出,這里創(chuàng)建的 " 索引 " 不需要使用傳統(tǒng)的索引結(jié)構(gòu)。例如, Oracle 文本索引就使用了一組表來(lái)實(shí)現(xiàn)其索引概念。

  首先,我們要確定數(shù)據(jù)庫(kù)運(yùn)行在何種優(yōu)化模式下,相應(yīng)的參數(shù)是:optimizer_mode??稍趕vrmgrl中運(yùn)行"show parameter optimizer_mode"來(lái)查看。ORACLE V7以來(lái)缺省的設(shè)置應(yīng)是"choose",即如果對(duì)已分析的表查詢(xún)的話(huà)選擇CBO,否則選擇RBO。如果該參數(shù)設(shè)為"rule",則不論表是否分析過(guò),一概選用RBO,除非在語(yǔ)句中用hint強(qiáng)制。

  查找原因的步驟

  首先,我們要確定數(shù)據(jù)庫(kù)運(yùn)行在何種優(yōu)化模式下,相應(yīng)的參數(shù)是:optimizer_mode??稍趕vrmgrl中運(yùn)行"show parameter optimizer_mode"來(lái)查看。ORACLE V7以來(lái)缺省的設(shè)置應(yīng)是"choose",即如果對(duì)已分析的表查詢(xún)的話(huà)選擇CBO,否則選擇RBO。如果該參數(shù)設(shè)為"rule",則不論表是否分析過(guò),一概選用RBO,除非在語(yǔ)句中用hint強(qiáng)制。

  其次,檢查被索引的列或組合索引的首列是否出現(xiàn)在PL/SQL語(yǔ)句的WHERE子句中,這是"執(zhí)行計(jì)劃"能用到相關(guān)索引的必要條件。

  第三,看采用了哪種類(lèi)型的連接方式。ORACLE的共有Sort Merge Join(SMJ)、Hash Join(HJ)和Nested Loop Join(NL)。在兩張表連接,且內(nèi)表的目標(biāo)列上建有索引時(shí),只有Nested Loop才能有效地利用到該索引。SMJ即使相關(guān)列上建有索引,最多只能因索引的存在,避免數(shù)據(jù)排序過(guò)程。HJ由于須做HASH運(yùn)算,索引的存在對(duì)數(shù)據(jù)查詢(xún)速度幾乎沒(méi)有影響。

  第四,看連接順序是否允許使用相關(guān)索引。假設(shè)表emp的deptno列上有索引,表dept的列deptno上無(wú)索引,WHERE語(yǔ)句有emp.deptno=dept.deptno條件。在做NL連接時(shí),emp做為外表,先被訪(fǎng)問(wèn),由于連接機(jī)制原因,外表的數(shù)據(jù)訪(fǎng)問(wèn)方式是全表掃描,emp.deptno上的索引顯然是用不上,最多在其上做索引全掃描或索引快速全掃描。

  第五,是否用到系統(tǒng)數(shù)據(jù)字典表或視圖。由于系統(tǒng)數(shù)據(jù)字典表都未被分析過(guò),可能導(dǎo)致極差的"執(zhí)行計(jì)劃"。但是不要擅自對(duì)數(shù)據(jù)字典表做分析,否則可能導(dǎo)致死鎖,或系統(tǒng)性能下降。

  第六,索引列是否函數(shù)的參數(shù)。如是,索引在查詢(xún)時(shí)用不上。

  第七,是否存在潛在的數(shù)據(jù)類(lèi)型轉(zhuǎn)換。如將字符型數(shù)據(jù)與數(shù)值型數(shù)據(jù)比較,ORACLE會(huì)自動(dòng)將字符型用to_number()函數(shù)進(jìn)行轉(zhuǎn)換,從而導(dǎo)致第六種現(xiàn)象的發(fā)生。

  第八,是否為表和相關(guān)的索引搜集足夠的統(tǒng)計(jì)數(shù)據(jù)。對(duì)數(shù)據(jù)經(jīng)常有增、刪、改的表最好定期對(duì)表和索引進(jìn)行分析,可用SQL語(yǔ)句"analyze table xxxx compute statistics for all indexes;"。ORACLE掌握了充分反映實(shí)際的統(tǒng)計(jì)數(shù)據(jù),才有可能做出正確的選擇。

  第九,索引列的選擇性不高。

  我們假設(shè)典型情況,有表emp,共有一百萬(wàn)行數(shù)據(jù),但其中的emp.deptno列,數(shù)據(jù)只有4種不同的值,如10、20、30、40。雖然emp數(shù)據(jù)行有很多,ORACLE缺省認(rèn)定表中列的值是在所有數(shù)據(jù)行均勻分布的,也就是說(shuō)每種deptno值各有25萬(wàn)數(shù)據(jù)行與之對(duì)應(yīng)。假設(shè)SQL搜索條件DEPTNO=10,利用deptno列上的索引進(jìn)行數(shù)據(jù)搜索效率,往往不比全表掃描的高,ORACLE理所當(dāng)然對(duì)索引"視而不見(jiàn)",認(rèn)為該索引的選擇性不高。

  但我們考慮另一種情況,如果一百萬(wàn)數(shù)據(jù)行實(shí)際不是在4種deptno值間

關(guān)鍵詞標(biāo)簽:Oracle索引

相關(guān)閱讀

文章評(píng)論
發(fā)表評(píng)論

熱門(mén)文章 Oracle中使用alter table來(lái)增加,刪除,修改列的語(yǔ)法 Oracle中使用alter table來(lái)增加,刪除,修改列的語(yǔ)法 oracle中使用SQL語(yǔ)句修改字段類(lèi)型-oracle修改SQL語(yǔ)句案例 oracle中使用SQL語(yǔ)句修改字段類(lèi)型-oracle修改SQL語(yǔ)句案例 誤刪Oracle數(shù)據(jù)庫(kù)實(shí)例的控制文件 誤刪Oracle數(shù)據(jù)庫(kù)實(shí)例的控制文件 為UNIX服務(wù)器設(shè)置Oracle全文檢索 為UNIX服務(wù)器設(shè)置Oracle全文檢索

相關(guān)下載

    人氣排行 oracle中使用SQL語(yǔ)句修改字段類(lèi)型-oracle修改SQL語(yǔ)句案例 Oracle中使用alter table來(lái)增加,刪除,修改列的語(yǔ)法 ORACLE SQL 判斷字符串是否為數(shù)字的語(yǔ)句 ORACLE和SQL語(yǔ)法區(qū)別歸納(1) oracle grant 授權(quán)語(yǔ)句 ORACLE修改IP地址后如何能夠使用 如何加速Oracle大批量數(shù)據(jù)處理 Oracle刪除表的幾種方法