Oracle-表分析和索引分析解读
概述
當表沒有做分析的時候,Oracle 會使用動態采樣來收集統計信息。 獲取準確的段對象(表,表分區,索引等)的分析數據,是CBO存在的基石,CBO的機制就是收集盡可能多的對象信息和系統信息,通過對這些信息進行計算,分析,評估,最終得出一個成本最低的執行計劃。
所以對于CBO,數據段的分析就非常重要。
分析SQL
analyze table tablename compute statistics等同于 analyze table tablename compute statistics for table for all indexes for all columnsfor table的統計信息存在于視圖:user_tables 、all_tables、dba_tables
for allindexes的統計信息存在于視圖: user_indexes 、all_indexes、dba_indexes
for allcolumns的統計信息存在于試圖:user_tab_columns、all_tab_columns、dba_tab_columns
或者
SQL> exec dbms_stats.gather_table_stats(user,'xiaogongjiang');生成的統計信息會存在于user_tables這個視圖,查看一下
select * from user_tables where table_name=table_name;觀察一下NUM_ROWS,BLOCKS,AVG_SPACE,AVG_ROW_LEN幾列你就會明白,這就是變化。
刪除SQL
analyze table tablename delete statistics 會刪除所有的statistics作用
Oracle分析表的作用:為了使基于CBO的執行計劃更加準確
栗子
數據準備
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 Connected as xx@xgjSQL> create table xiaogongjiang as select a.OBJECT_ID ,a.OBJECT_NAME from dba_objects a ;--創建表Table createdSQL> select count(1) from xiaogongjiang;COUNT(1) ----------35183SQL> create index idx_object_id on xiaogongjiang(object_id);--在object_id建立索引Index createdSQL>分析前的數據及執行計劃
SQL> select num_rows, avg_row_len, blocks, last_analyzed from user_tables where table_name = 'XIAOGONGJIANG';--表的信息NUM_ROWS AVG_ROW_LEN BLOCKS LAST_ANALYZED ---------- ----------- ---------- -------------SQL> select blevel,leaf_blocks,distinct_keys,last_analyzed from user_indexes where table_name='XIAOGONGJIANG';--索引信息BLEVEL LEAF_BLOCKS DISTINCT_KEYS LAST_ANALYZED ---------- ----------- ------------- -------------從查詢結果看出,表的行數,行長,占用的數據塊數及最后的分析時間都是空。 索引的相關信息也沒有,說明這個表和說因都沒有被分析,如果此時有一條SQL 對表做查詢,CBO 由于無法獲取這些信息,很可能生成錯誤的執行計劃。
查詢執行計劃
--執行sql,以便存到shared pool中 SQL>select /*+dynamic_sampling(xiaogongjiang 0) */ * from XIAOGONGJIANG where object_id>30; .....省略輸出-- 查詢出上個執行腳本對應的sql_id:5h16pnkvs0r5z SQL>select * from v$sql a where a.SQL_TEXT like '%select /*+dynamic_sampling(xiaogongjiang 0) */ * from XIAOGONGJIANG where object_id>30%'; .....省略輸出--使用dbms_xplan.display_cursor查看sql真正的執行計劃 SQL>select * from table(dbms_xplan.display_cursor('5h16pnkvs0r5z'));導出html,查看如下
在Oracle 10g以后,如果一個表沒有做分析,數據庫將自動對它做動態采樣分析,
所以這里采用hint的方式將動態采樣的級別設置為0,即不使用動態采樣。
分析后的數據及執行計劃
第一種方式
SQL> analyze table xiaogongjiang compute statistics ;Table analyzed第二種方式(推薦)
SQL> exec dbms_stats.gather_table_stats(user,'xiaogongjiang');PL/SQL procedure successfully completedSQL> 第一個參數為用戶,第二個參數為表通過DBMS_STATS包來分析,從9i 開始,Oracle 推薦使用DBMS_STATS包對表進行分析操作,因為DBMS_STATS 提供了更多的功能,以及靈活的操作方式。
SQL> select num_rows, avg_row_len, blocks, last_analyzed from user_tables where table_name = 'XIAOGONGJIANG';NUM_ROWS AVG_ROW_LEN BLOCKS LAST_ANALYZED ---------- ----------- ---------- -------------35183 27 152 2016-12-02 0:SQL> select blevel,leaf_blocks,distinct_keys,last_analyzed from user_indexes where table_name='XIAOGONGJIANG';BLEVEL LEAF_BLOCKS DISTINCT_KEYS LAST_ANALYZED ---------- ----------- ------------- -------------1 77 35180 2016-12-02 0:從上面的結果,可以看出DBMS_STATS.gather_table_stats已經對表和索引都做了分析。 現在我們在來看一下執行計劃。
SQL>select * from xiaogongjiang where object_id>30;SQL>select * from v$sql a where a.SQL_TEXT like '%select * from xiaogongjiang where object_id>30%';SQL>select * from table(dbms_xplan.display_cursor('gzspgs4btcpuf'));從這個計劃,我們看出CBO 估算出的結果是35153條記錄,與實際的35183很近。 此時選擇全表掃描更優。 通過這個例子,我們也看出了分析對執行計劃的重要性。
總結
以上是生活随笔為你收集整理的Oracle-表分析和索引分析解读的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Shell脚本攻略01-简介/终端打印
- 下一篇: Shell脚本攻略02-玩转变量与环境变