表統計信息的收集時間能夠從user_table的analylize_time中得知,可是統計信息是否準確,仍是很差判斷,上課中郭老師提出了採用dbms_xplan.display_cursor查看收集的信息能夠幫助咱們判斷統計信息是否陳舊。sql
以下是具體的操做方式:session
SQL> set linesize 1000ide
SQL> Set pagesize 100性能
SQL> drop table test1 purge;spa
表已刪除。orm
SQL> drop table test2 purge;ip
表已刪除。內存
SQL> create table test1 as select * from dba_objects where rownum <=100;hash
表已建立。io
SQL> create table test2 as select * from dba_objects where rownum <=1000;
表已建立。
-- statistics_level有三個值,basic,typical,all。若是爲basic則關閉全部性能數據的收集;若是是typical,除了plan_executetion_statistics和OS statistics不能收集,其餘都能收集;all即都收集。
--statistics_level設爲all,收集全部信息
SQL> alter session set statistics_level=all;
會話已更改。
--採用hint讓其不要動態收集統計信息(通常統計信息沒收集過的表在執行sql時會動態收集)
SQL> select /*+Dynamic_sampling(0)*/count(*)
2 from test1 t1, test2 t2
3 where t1.object_id = t2.object_id;
COUNT(*)
----------
100
--查看最新收集的信息(dbms_xplan.display_cursor)
SQL> SELECT * FROM table(dbms_xplan.display_cursor(NULL,NULL,'allstats last'));
PLAN_TABLE_OUTPUT
---------------------------------------------------------
SQL_ID 55ga693yggjkd, child number 0
-------------------------------------
select /*+Dynamic_sampling(0)*/count(*) from test1 t1, test2 t2
where t1.object_id = t2.object_id
Plan hash value: 2544416891
---------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |
---------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.06 | 20 | 15 | | | |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.06 | 20 | 15 | | | |
|* 2 | HASH JOIN | | 1 | 1307 | 100 |00:00:00.06 | 20 | 15 | 1517K | 1517K | 1260K (0)|
| 3 | TABLE ACCESS FULL| TEST1 | 1 | 409 | 100 |00:00:00.06 | 4 | 2 | | | |
| 4 | TABLE ACCESS FULL| TEST2 | 1 | 1307 | 1000 |00:00:00.01 | 16 | 13 | | | |
---------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
已選擇22行。
如上信息能夠看到,表信息在沒收集的狀況下,e-rows(評估的行數)和a-rows(實際行數)存在很大的差距。
--對錶進行手動收集統計信息
SQL> exec dbms_stats.gather_table_stats(user,'test1');
PL/SQL 過程已成功完成。
SQL> exec dbms_stats.gather_table_stats(user,'test2');
PL/SQL 過程已成功完成。
--再次執行該語句並查看其收集的信息
SQL> SELECT count(*)
2 from test1 t1, test2 t2
3 where t1.object_id = t2.object_id;
COUNT(*)
----------
100
SQL> SELECT * FROM table(dbms_xplan.display_cursor(NULL,NULL,'allstats last'));
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------
SQL_ID dt23w69fu80v4, child number 0
------------------------------------------------------------------------------------------
SELECT count(*) from test1 t1, test2 t2 where t1.object_id =
t2.object_id
Plan hash value: 2544416891
------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 20 | | | |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | 20 | | | |
|* 2 | HASH JOIN | | 1 | 100 | 100 |00:00:00.01 | 20 | 1517K| 1517K| 1463K (0)|
| 3 | TABLE ACCESS FULL| TEST1 | 1 | 100 | 100 |00:00:00.01 | 4 | | | |
| 4 | TABLE ACCESS FULL| TEST2 | 1 | 1000 | 1000 |00:00:00.01 | 16 | | | |
------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
已選擇22行。
表統計信息準確後,發現評估的行數與實際的行數徹底一致。
附:查詢出的統計信息標題含義
Starts:該sql執行的次數。
E-Rows:執行計劃預計的行數。
A-Rows:實際返回的行數。
A-Time:每一步實際執行的時間(HH:MM:SS.FF),根據這一行能夠知道該sql耗時在哪一個地方。
Buffers:每一步實際執行的邏輯讀或一致性讀。
Reads:物理讀。
OMem、1Mem:執行所需的內存評估值,OMem爲最優執行模式所需內存的評估值,1Mem爲one-pass模式所需內存的評估值。
O/1/M :最優/one-pass/multipass執行的次數。
Used-Mem:耗的內存。
注:若是執行中都沒有涉及到的項,則在收集中就不會出現該項,如上述第一次執行的sql在收集的信息中有reads,可是表收集統計信息後再次執行由於不存在物理讀,因此在第二個收集的信息中就沒有reads這一項。