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