Oracle對(duì)表、索引和簇的分析
?
??? 分析Oracle的表、索引或簇,可以采集其有關(guān)的數(shù)據(jù),或者校驗(yàn)其存儲(chǔ)格式的合法性。還可以分析這些模式對(duì)象以便收集或更新指定對(duì)象的統(tǒng)計(jì)數(shù)據(jù)。當(dāng)發(fā)布DDL語句時(shí),參照對(duì)象的統(tǒng)計(jì)數(shù)據(jù)被用于確定該語句的最有效的執(zhí)行方案。即使用CBO就需要有足夠的分析數(shù)據(jù)。
?
?
一、使用表、索引、簇的統(tǒng)計(jì)表
?
??? 使用ANALYZE語句來收集統(tǒng)計(jì)信息到數(shù)據(jù)字典中。當(dāng)使用CBO來執(zhí)行SQL時(shí),就會(huì)利用這些統(tǒng)計(jì)數(shù)據(jù)以得出結(jié)論。
?
??? COMPUTER STATISTICS
?
??? 當(dāng)計(jì)算統(tǒng)計(jì)數(shù)字時(shí),掃描整個(gè)對(duì)象,收集關(guān)于此對(duì)象的數(shù)據(jù)。Oracle用這些數(shù)據(jù)來計(jì)算此對(duì)象的精確統(tǒng)計(jì)數(shù)據(jù)。在這些計(jì)算出的統(tǒng)計(jì)數(shù)據(jù)中,整個(gè)對(duì)象的微小變化都被計(jì)算出來。因?yàn)闉榱耸占?jì)算統(tǒng)計(jì)數(shù)據(jù)的信息要掃描整個(gè)對(duì)象,所以對(duì)象的體積越大,收集所有信息所要做的工作就越多。
?
??? ESTIMATE STATISTICS
?
??? 當(dāng)估計(jì)統(tǒng)計(jì)數(shù)據(jù)時(shí),Oracle收集對(duì)象的各部分有代表性的信息。該信息的子集提供了有關(guān)該對(duì)象合理的、估計(jì)的統(tǒng)計(jì)數(shù)據(jù)。估計(jì)出的統(tǒng)計(jì)出具的精確度取決于Oracle所使用的樣例的代表性。因?yàn)槭占烙?jì)統(tǒng)計(jì)數(shù)據(jù)只是掃描對(duì)象的幾個(gè)部分,因此能快速得分析一個(gè)對(duì)象,也可以隨意得指定Oracle在做估計(jì)時(shí)所使用的行的數(shù)量和百分比。
?
??? 注意:在計(jì)算表或簇的統(tǒng)計(jì)數(shù)據(jù)時(shí),需要有足夠的臨時(shí)空間。但分析索引時(shí)不需要臨時(shí)空間。
?
?
二、使用ANALYZE語句計(jì)算統(tǒng)計(jì)數(shù)據(jù)
?
??? ANALYZE TABLE emp COMPUTE STATISTICS; --完全統(tǒng)計(jì)
??? ANALYZE TABLE emp ESTIMATE STATISTICS; --默認(rèn)的1064行統(tǒng)計(jì)樣例
??? ANALYZE TABLE emp ESTIMATE STATISTICS SAMPLE 2000 ROWS; --用2000行做統(tǒng)計(jì)樣例
??? ANALYZE TABLE emp ESTIMATE STATISTICS SAMPLE 33 PERCENT; --用33%做統(tǒng)計(jì)樣例
?
??? 統(tǒng)計(jì)得到的信息有以下這些(帶*號(hào)的表示數(shù)據(jù)是精確的)
?
??? 表:
??? ● 行數(shù)
??? ● 已經(jīng)使用的數(shù)據(jù)塊數(shù)*
??? ● 從未使用的數(shù)據(jù)塊數(shù)
??? ● 平均可用的空閑空間
??? ● 鏈接行的數(shù)目
??? ● 平均行長(zhǎng)度
??? ● 列中不同的值的數(shù)目
??? ● 列的下限值*
??? ● 列的上限值*
?
??? 索引:
??? ● 索引層次*
??? ● 葉子數(shù)據(jù)塊的數(shù)目
??? ● 不同的鍵的數(shù)目
??? ● 每個(gè)鍵的葉子數(shù)據(jù)塊的平均數(shù)目
??? ● 每個(gè)鍵的數(shù)據(jù)塊的平均數(shù)目
??? ● 分簇因子
?
??? 注意:若一個(gè)索引已標(biāo)記為UNUSABLE,則在分析時(shí)報(bào)錯(cuò),必須刪除或重建后才能分析。
?
??? 簇:
??? ● 簇鍵鏈的平均長(zhǎng)度
?
??? 注:當(dāng)分析簇的統(tǒng)計(jì)數(shù)據(jù)時(shí),簇中的表盒索引的統(tǒng)計(jì)信息會(huì)被自動(dòng)收集
?
?
三、操作對(duì)象的統(tǒng)計(jì)數(shù)據(jù)
?
1、查看統(tǒng)計(jì)信息
?
??? DBA|ALL|USER_INDEXES
??? DBA|ALL|USER_TABLES
??? DBA|ALL|USER_TAB_COLUMNS
?
??? 注意:這些表中的上面所列統(tǒng)計(jì)信息,如果不ANALYZE的話,是一直不變的。
?
2、刪除統(tǒng)計(jì)信息
?
??? ANALYZE TABLE emp DELETE STATISTICS;
?
??? 刪除后可以防止table再使用CBO
?
3、其他的統(tǒng)計(jì)方法
?
??? 使用PLSQL包也可以對(duì)表進(jìn)行數(shù)據(jù)統(tǒng)計(jì)分析
?
??? DBMS_STATS:這個(gè)當(dāng)然是最強(qiáng)大的分析包了
??? DBMS_UTILITY.ANALYZE_SCHEMA:可直接分析SCHEMA中所有對(duì)象
??? DBMS_DDL.ANALYZE_OBJECT:收集對(duì)象的的統(tǒng)計(jì)信息
?
?
四、校驗(yàn)表、索引、簇和物化視圖
?
??? 為了校驗(yàn)表、索引、簇和物化視圖的結(jié)構(gòu)的完整性,使用帶有VALIDATE STRUCTURE選項(xiàng)的ANALYZE語句,如果返回錯(cuò)誤消息,則說明該對(duì)象已損壞。如果對(duì)象損壞,則需要?jiǎng)h除并重建。如果是物化視圖,則僅需要重新完全刷新一遍
?
??? 校驗(yàn)的語句如下:
??? ANALYZE TABLE emp VALIDATE STRUCTURE;
?
??? 如果需要校驗(yàn)與某對(duì)象有關(guān)聯(lián)的所有對(duì)象是否有效,則使用CASCADE子句:
??? ANALYZE TABLE emp VALIDATE STRUCTURE CASCADE;
?
??? 再加入聯(lián)機(jī)結(jié)構(gòu)校驗(yàn):
??? ANALYZE TABLE emp VALIDATE STRUCTURE CASCADE ONLINE;
???
?
五、列出表和簇的鏈接行
?
??? 可使用LIST CHAINED ROWS選項(xiàng)的ANALYZE語句,查看表或簇中鏈接的或遷移的行。這條語句的執(zhí)行結(jié)果存儲(chǔ)在制定的表中,該表被明確得創(chuàng)建,以便直接接收由LIST CHAINED ROWS子句返回的值。
?
1、創(chuàng)建CHAINED_ROWS表
?
??? 創(chuàng)建用于接收由ANALYZE LIST CHAINED ROWS語句返回的數(shù)據(jù)的表,執(zhí)行'D:\oracle\ora92\rdbms\admin\utlchain.sql'(這個(gè)腳本其實(shí)就是一個(gè)簡(jiǎn)單的table創(chuàng)建語句)。
?
??? 創(chuàng)建之后,使用ANALYZE語句的語法如下:
??? ANALYZE CLUSTER emp_dept CHAINED ROWS INTO CHAINED_ROWS;
?
2、刪除表中的遷移或鏈接行
?
??? 使用CHAINED_ROWS表中的信息,可減少或刪除現(xiàn)存表中的遷移或鏈接行,步驟如下:
?
??? ①使用ANALYZE語句收集遷移或鏈接行信息
??? ANALYZE TABLE order_hist LIST CHAINED ROWS;
?
??? ②查詢輸出表
??? SELECT * FROM CHAINED_ROWS
??? WHERE TABLE_NAME = 'ORDER_HIST';
?
??? 在輸出結(jié)果中會(huì)顯示遷移或者鏈接的所有行
?
??? ③如果輸出表顯示出有許多遷移或鏈接行,則開始執(zhí)行刪除遷移行:
?
??? ④創(chuàng)建一個(gè)與現(xiàn)存表相同列的中間表,以便保留遷移或鏈接行
??? CREATE TABLE int_order_hist
????? AS SELECT * FROM order_hist
???? WHERE ROWID IN
?????????? (SELECT HEAR_ROWID
????????????? FROM CHAINED_ROWS
???????????? WHERE TABLE_NAME = 'ORDER_HIST');
?
??? ⑤從現(xiàn)存的表中刪除遷移或鏈接行
??? DELETE FROM order_hist
???? WHERE ROWID IN
?????????? (SELECT HEAR_ROWID
????????????? FROM CHAINED_ROWS
???????????? WHERE TABLE_NAME = 'ORDER_HIST');
?
??? ⑥把中間表中的行插入到現(xiàn)存表中
??? INSERT INTO order_hist
??? SELECT * FROM int_order_hist;
?
??? ⑦刪除中間表
??? DROP TABLE int_order_hist;
?
??? ⑧從輸出表中刪除步驟1所收集的信息
??? DELETE FROM CHAINED_ROWS
???? WHERE TABLE_NAME = 'ORDER_HIST';
?
??? ⑨再次使用ANALYZE語句,查詢輸出表
?
??? ⑩再次輸出表中的所有行都是鏈接行,通過增加數(shù)據(jù)塊大小就能消除鏈接行。但是很多情況下,鏈接問題不可避免。
?
?
?
?