索引( Index )是常見的數(shù)據(jù)庫(kù)對(duì)象,它的設(shè)置好壞、使用是否得當(dāng),極大地影響數(shù)據(jù)庫(kù)應(yīng)用程序和Database 的性能。雖然有許多資料講索引的用法, DBA 和 Developer 們也經(jīng)常與它打交道,但筆者發(fā)現(xiàn),還是有不少的人對(duì)它存在誤解,因此針對(duì)使用中的常見問題,講三個(gè)問題。此文所有示例所用的數(shù)據(jù)庫(kù)是 Oracle 8.1.7 OPS on HP N series ,示例全部是真實(shí)數(shù)據(jù),讀者不需要注意具體的數(shù)據(jù)大小,而應(yīng)注意在使用不同的方法后,數(shù)據(jù)的比較。本文所講基本都是陳詞濫調(diào),但是筆者試圖通過實(shí)際的例子,來真正讓您明白事情的關(guān)鍵。
第一講、索引并非總是最佳選擇
如果發(fā)現(xiàn)Oracle 在有索引的情況下,沒有使用索引,這并不是Oracle 的優(yōu)化器出錯(cuò)。在有些情況下,Oracle 確實(shí)會(huì)選擇全表掃描(Full Table Scan),而非索引掃描(Index Scan)。這些情況通常有:
1. 表未做statistics, 或者 statistics 陳舊,導(dǎo)致 Oracle 判斷失誤。
2. 根據(jù)該表?yè)碛械挠涗洈?shù)和數(shù)據(jù)塊數(shù),實(shí)際上全表掃描要比索引掃描更快。
對(duì)第1種情況,最常見的例子,是以下這句sql 語(yǔ)句:
在未作statistics 之前,它使用全表掃描,需要讀取6000多個(gè)數(shù)據(jù)塊(一個(gè)數(shù)據(jù)塊是8k), 做了statistics 之后,使用的是 INDEX (FAST FULL SCAN) ,只需要讀取450個(gè)數(shù)據(jù)塊。但是,statistics 做得不好,也會(huì)導(dǎo)致Oracle 不使用索引。
第2種情況就要復(fù)雜得多。一般概念上都認(rèn)為索引比表快,比較難以理解什么情況下全表掃描要比索引掃描快。為了講清楚這個(gè)問題,這里先介紹一下Oracle 在評(píng)估使用索引的代價(jià)(cost)時(shí)兩個(gè)重要的數(shù)據(jù):CF(Clustering factor) 和 FF(Filtering factor).
CF: 所謂 CF, 通俗地講,就是每讀入一個(gè)索引塊,要對(duì)應(yīng)讀入多少個(gè)數(shù)據(jù)塊。
FF: 所謂 FF, 就是該sql 語(yǔ)句所選擇的結(jié)果集,占總的數(shù)據(jù)量的百分比。
大約的計(jì)算公式是:FF * (CF + 索引塊個(gè)數(shù)) ,由此估計(jì)出,一個(gè)查詢, 如果使用某個(gè)索引,會(huì)需要讀入的數(shù)據(jù)塊塊數(shù)。需要讀入的數(shù)據(jù)塊越多,則 cost 越大,Oracle 也就越可能不選擇使用 index. (全表掃描需要讀入的數(shù)據(jù)塊數(shù)等于該表的實(shí)際數(shù)據(jù)塊數(shù))
其核心就是, CF 可能會(huì)比實(shí)際的數(shù)據(jù)塊數(shù)量大。CF 受到索引中數(shù)據(jù)的排列方式影響,通常在索引剛建立時(shí),索引中的記錄與表中的記錄有良好的對(duì)應(yīng)關(guān)系,CF 都很小;在表經(jīng)過大量的插入、修改后,這種對(duì)應(yīng)關(guān)系越來越亂,CF 也越來越大。此時(shí)需要 DBA 重新建立或者組織該索引。
如果某個(gè)sql 語(yǔ)句以前一直使用某索引,較長(zhǎng)時(shí)間后不再使用,一種可能就是 CF 已經(jīng)變得太大,需要重新整理該索引了。
FF 則是Oracle 根據(jù) statistics 所做的估計(jì)。比如, mytables 表有32萬(wàn)行,其主鍵myid的最小值是1,最大值是409654,考慮以下sql 語(yǔ)句:
這兩句看似差不多的 sql 語(yǔ)句,對(duì)Oracle 而言,卻有巨大的差別。因?yàn)榍罢叩?nbsp;FF 是100%, 而后者的 FF 可能只有 1%。如果它的CF 大于實(shí)際的數(shù)據(jù)塊數(shù),則Oracle 可能會(huì)選擇完全不同的優(yōu)化方式。而實(shí)際上,在我們的數(shù)據(jù)庫(kù)上的測(cè)試驗(yàn)證了我們的預(yù)測(cè). 以下是在HP 上執(zhí)行時(shí)它們的 explain plan:
第一句:
已選擇325917行。
第二句:
顯而易見,第1句沒有使用索引,第2句使用了主鍵索引pk_mytables. FF的巨大影響由此可見一斑。由此想到,我們?cè)趯憇ql 語(yǔ)句時(shí),如果預(yù)先估計(jì)一下 FF, 你就幾乎可以預(yù)見到 Oracle 會(huì)否使用索引。
[NextPage]
第二講、索引也有好壞
[NextPage]
第三講、索引再好,不用也是白搭
[1] [2] 下一頁(yè)
正在看的ORACLE教程是:Oracle Index 的三個(gè)問題。設(shè)你設(shè)置了一個(gè)非常好的索引,任何傻瓜都知道應(yīng)該使用它,但是Oracle 卻偏偏不用,那么,需要做的第一件事情,是審視你的 sql 語(yǔ)句。
上一頁(yè)
上一頁(yè) [1] [2]
新聞熱點(diǎn)
疑難解答
圖片精選