• 验证表统计信息是否不对


    表统计信息的收集时间可以从user_table的analylize_time中得知,但是统计信息是否准确,还是不好判断,上课中郭老师提出了采用dbms_xplan.display_cursor查看收集的信息可以帮助我们判断统计信息是否陈旧。

    如下是具体的操作方式:

    SQL> set linesize 1000

    SQL> Set pagesize 100

    SQL> drop table test1 purge;

    表已删除。

    SQL> drop table test2 purge;

    表已删除。

    SQL> create table test1 as select * from dba_objects where rownum <=100;

    表已创建。

    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这一项。

  • 相关阅读:
    Android第三次作业
    Android第二次作业
    2016-2017-2软件工程课程总结
    软件工程——个人总结
    软件工程——团队答辩
    软件工程——团队作业4
    软件工程——团队作业3
    软件工程——团队作业2
    软件工程——团队作业1
    软件工程第二次作业——结对编程
  • 原文地址:https://www.cnblogs.com/lanzi/p/3469818.html
Copyright © 2020-2023  润新知