驗證表統計信息是否不對

表統計信息的收集時間能夠從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這一項。

相關文章
相關標籤/搜索