Oracle11g/12c dbms_stat extended stats 实验的示例分析

技术Oracle11g/12c dbms_stat extended stats 实验的示例分析Oracle11g/12c dbms_stat extended stats 实验的示例分析,相信很多没有经验的人对此束手无

Oracle11g/12c dbms_stat扩展统计实验的示例分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

目的:

1.测试下dbms_stats的扩展统计包的使用效果,是否可以在选择率低的情况下,解决执行计划/cardi natity基数行不准的问题并且是只验证extended stats 包的使用效果 :d :

环境:

1.windows 7 64位

2.甲骨文12.2.0.164公司位

3.使用演示程序的销售历史,上海用户测试。

4.先手动安装下销售历史范例数据

步骤:

1.销售表先插入50 行,

2.分析表,获得统计信息

3.插入大量数据,让统计信息不准

4.使用扩展状态分析包

5.对比执行计划

步骤1-2 :

alter session set statistics _ level=all;

设置线条大小120

显示参数统计信息_级别;

名称类型值

– – –

统计级别字符串全部

结构化查询语言

插入到销售中从sales_02中选择*其中rownum=50

EXEC DBMS_STATS .聚集_表格_统计(用户,’销售’);

从用户选项卡列中选择列名,数字,直方图,其中table _ name=’ SALES

结构化查询语言从用户选项卡列中选择列名,数字,直方图,其中table _ name=’ SALES

列_ NAM NUM _ DISTINCT直方图

– – –

生产标识一频率

客户身份证50无

时间标识2无

频道标识2频率

促销标识一频率

数量S 1无

量_索尔2频率

>
select num_rows from user_tables where table_name = 'SALES'  ;
SQL> select num_rows from user_tables where table_name = 'SALES'  ;

  NUM_ROWS
———-
        50

select count(*) from sales a where amount_sold >
( select avg(amount_sold)  from sales b
where b.prod_id = a.prod_id
and channel_id = 3 and promo_id = 999 )
and channel_id = 3 and promo_id = 999 ;

  COUNT(*)
———-
       309

已用时间:  00: 00: 00.02
SQL>

select * from table(dbms_xplan.display_cursor(NULL,NULL,'allstats last')) ;

PLAN_TABLE_OUTPUT
————————————————————————————————————————
SQL_ID  18vj1zs6jut5g, child number 0
————————————-
select count(*) from sales a where amount_sold > ( select
avg(amount_sold)  from sales b where b.prod_id = a.prod_id and
channel_id = 3 and promo_id = 999 ) and channel_id = 3 and promo_id =
999

Plan hash value: 1265065521

—————————————————————————————-
| Id  | Operation            | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
|   0 | SELECT STATEMENT     |       |      1 |        |      1 |00:00:00.01 |      14 |
|   1 |  SORT AGGREGATE      |       |      1 |      1 |      1 |00:00:00.01 |      14 |
|*  2 |   FILTER             |       |      1 |        |      0 |00:00:00.01 |      14 |
|*  3 |    TABLE ACCESS FULL | SALES |      1 |     48 |     49 |00:00:00.01 |       7 |
|   4 |    SORT AGGREGATE    |       |      1 |      1 |      1 |00:00:00.01 |       7 |
|*  5 |     TABLE ACCESS FULL| SALES |      1 |     48 |     49 |00:00:00.01 |       7 |
—————————————————————————————-
  

CHANNEL_ID            2 FREQUENCY
PROMO_ID              1 FREQUENCY

  NUM_ROWS
———-
      50
      
计算 cardinality      
      1/2 * 1 * 50 = 25  ,
基数算出来是 25

     
步骤3:

SQL> select count(*) from sales ;

  COUNT(*)
———-
   2756579

再次执行sql, 并看执行计划:

select count(*) from sales a where amount_sold >
( select avg(amount_sold)  from sales b
where b.prod_id = a.prod_id
and channel_id = 3 and promo_id = 999 )
and channel_id = 3 and promo_id = 999 ;

   
select * from table(dbms_xplan.display_cursor(NULL,NULL,'allstats last')) ;
PLAN_TABLE_OUTPUT
——————————————————————————————
SQL_ID  18vj1zs6jut5g, child number 0
————————————-
select count(*) from sales a where amount_sold > ( select
avg(amount_sold)  from sales b where b.prod_id = a.prod_id and
channel_id = 3 and promo_id = 999 ) and channel_id = 3 and promo_id =
999

Plan hash value: 1265065521

—————————————————————————————-
| Id  | Operation            | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |

PLAN_TABLE_OUTPUT
——————————————————————————————
—————————————————————————————-
|   0 | SELECT STATEMENT     |       |      1 |        |      1 |00:01:53.45 |    2336K|
|   1 |  SORT AGGREGATE      |       |      1 |      1 |      1 |00:01:53.45 |    2336K|
|*  2 |   FILTER             |       |      1 |        |    709K|00:01:53.33 |    2336K|
|*  3 |    TABLE ACCESS FULL | SALES |      1 |     48 |   1554K|00:00:00.98 |   13431 |
|   4 |    SORT AGGREGATE    |       |    173 |      1 |    173 |00:01:51.30 |    2323K|
|*  5 |     TABLE ACCESS FULL| SALES |    173 |     48 |   2131K|00:01:50.93 |    2323K|
—————————————————————————————-

48 VS  2131000  = 50000 倍

SQL> select num_rows from user_tables where table_name = 'SALES'  ;

  NUM_ROWS
———-
        50

使用 extended 包
select
dbms_stats.create_extended_stats(ownname => 'SH' , tabname =>
'SALES' , extension => '(CHANNEL_ID,PROMO_ID)' ) from dual ;

DBMS_STATS.CREATE_EXTENDED_STATS(OWNNAME=>'SH',TABNAME=>'SALES',EXTENSION=>'(CHANNEL_ID,PROMO_ID)')
————————————————————————————————————————
SYS_STU7$MLVU9QOBUF89709XS1VC9

已用时间:  00: 00: 01.65
SQL>
SQL>

exec dbms_stats.gather_table_stats(null,'SALES', method_opt => 'for columns SYS_STU7$MLVU9QOBUF89709XS1VC9 size 2' );  

select count(*) from sales a where amount_sold >
( select avg(amount_sold)  from sales b
where b.prod_id = a.prod_id
and channel_id = 3 and promo_id = 999 )
and channel_id = 3 and promo_id = 999 ;

alter system flush shared_pool;   
select * from table(dbms_xplan.display_cursor(NULL,NULL,'allstats last')) ;  

PLAN_TABLE_OUTPUT
———————————————————————————————————————–
SQL_ID  18vj1zs6jut5g, child number 0
————————————-
select count(*) from sales a where amount_sold > ( select
avg(amount_sold)  from sales b where b.prod_id = a.prod_id and
channel_id = 3 and promo_id = 999 ) and channel_id = 3 and promo_id =
999

Plan hash value: 4009253081

———————————————————————————————————————-
| Id  | Operation             | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
|   0 | SELECT STATEMENT      |         |      1 |        |      1 |00:00:01.79 |   26898 |       |    |             |
|   1 |  SORT AGGREGATE       |         |      1 |      1 |      1 |00:00:01.79 |   26898 |       |    |             |
|*  2 |   HASH JOIN           |         |      1 |  94910 |    709K|00:00:01.79 |   26898 |  1316K|  1316K| 1666K (0)|
|   3 |    VIEW               | VW_SQ_1 |      1 |     72 |     72 |00:00:00.92 |   13431 |       |    |             |
|   4 |     HASH GROUP BY     |         |      1 |     72 |     72 |00:00:00.92 |   13431 |  1106K|  1106K| 2480K (0)|
|*  5 |      TABLE ACCESS FULL| SALES   |      1 |   1554K|   1554K|00:00:00.48 |   13431 |       |    |             |
|*  6 |    TABLE ACCESS FULL  | SALES   |      1 |   1554K|   1554K|00:00:00.49 |   13431 |       |    |             |
———————————————————————————————————————-

SQL> select num_rows from user_tables where table_name = 'SALES'  ;

  NUM_ROWS
———-
   2756579
   
   
EXEC DBMS_STATS.GATHER_TABLE_STATS(user,'SALES');

SQL> select column_name, num_distinct, histogram from user_tab_columns where table_name = 'SALES'  ;

COLUMN_NAM NUM_DISTINCT HISTOGRAM
———- ———— ——————————
PROD_ID              72 FREQUENCY
CUST_ID            7059 NONE
TIME_ID            1460 NONE
CHANNEL_ID            4 FREQUENCY
PROMO_ID              4 FREQUENCY
QUANTITY_S            1 NONE
AMOUNT_SOL         3586 HYBRID

已选择 7 行。
CHANNEL_ID  PROMO_ID 各选择一个值,就是:

1/4 * 1/4 * 2756579 =  172286
           
基数是 172286
estimated rows : 1554000

去掉统计信息

这些都无效,
exec DBMS_STATS.DROP_EXTENDED_STATS(null,'SALES','(CHANNEL_ID,PROMO_ID)');
exec DBMS_STATS.DELETE_TABLE_STATS(ownname => 'SH',  tabname => 'SALES');
select ADDRESS, HASH_VALUE from V$SQLAREA where SQL_ID = '18vj1zs6jut5g';
ADDRESS          HASH_VALUE
—————- ———-
000007FF0465AB40  220030127
exec SYS.DBMS_SHARED_POOL.PURGE ('000007FF0465AB40,220030127', 'C');

select count(*) from sales a where amount_sold >
( select avg(amount_sold)  from sales b
where b.prod_id = a.prod_id
and channel_id = 3 and promo_id = 999 )
and channel_id = 3 and promo_id = 999 ;

SQL> select column_name, num_distinct, histogram from user_tab_columns where table_name = 'SALES'  ;

COLUMN_NAM NUM_DISTINCT HISTOGRAM
———- ———— ——————————
PROD_ID                 NONE
CUST_ID                 NONE
TIME_ID                 NONE
CHANNEL_ID              NONE
PROMO_ID                NONE
QUANTITY_S              NONE
AMOUNT_SOL              NONE

已选择 7 行。

SQL>  select num_rows from user_tables where table_name = 'SALES'  ;

  NUM_ROWS
———-

select * from table(dbms_xplan.display_cursor(NULL,NULL,'allstats last')) ;

Plan hash value: 4009253081

———————————————————————————————————————-
| Id  | Operation             | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |

PLAN_TABLE_OUTPUT
————————————————————————————————————————
———————————————————————————————————————-
|   0 | SELECT STATEMENT      |         |      1 |        |      1 |00:00:01.67 |   26898 |       |    |             |
|   1 |  SORT AGGREGATE       |         |      1 |      1 |      1 |00:00:01.67 |   26898 |       |    |             |
|*  2 |   HASH JOIN           |         |      1 |  95637 |    709K|00:00:01.67 |   26898 |  1316K|  1316K| 1583K (0)|
|   3 |    VIEW               | VW_SQ_1 |      1 |     72 |     72 |00:00:00.87 |   13431 |       |    |             |
|   4 |     HASH GROUP BY     |         |      1 |     72 |     72 |00:00:00.87 |   13431 |  1106K|  1106K| 2480K (0)|
|*  5 |      TABLE ACCESS FULL| SALES   |      1 |   1566K|   1554K|00:00:00.45 |   13431 |       |    |             |
|*  6 |    TABLE ACCESS FULL  | SALES   |      1 |   1566K|   1554K|00:00:00.45 |   13431 |       |    |             |
———————————————————————————————————————-

最后还是truncate table ,重新建立数据

truncate table sales ;

insert into sales select * from sales_02 where rownum <= 50 ;

EXEC DBMS_STATS.GATHER_TABLE_STATS(user,'SALES');

SQL> select column_name, num_distinct, histogram from user_tab_columns where table_name = 'SALES'  ;

COLUMN_NAM NUM_DISTINCT HISTOGRAM
———- ———— ——————————
PROD_ID               1 FREQUENCY
CUST_ID              50 NONE
TIME_ID               2 NONE
CHANNEL_ID            2 FREQUENCY
PROMO_ID              1 FREQUENCY
QUANTITY_S            1 NONE
AMOUNT_SOL            2 FREQUENCY

已选择 7 行。

SQL> select num_rows from user_tables where table_name = 'SALES'  ;

  NUM_ROWS
———-
        50

select count(*) from sales a where amount_sold >
( select avg(amount_sold)  from sales b
where b.prod_id = a.prod_id
and channel_id = 3 and promo_id = 999 )
and channel_id = 3 and promo_id = 999 ;
COUNT(*)
———
   709087
   
select * from table(dbms_xplan.display_cursor(NULL,NULL,'allstats last')) ;
Plan hash value: 1265065521

—————————————————————————————-
| Id  | Operation            | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |

PLAN_TABLE_OUTPUT
—————————————————————————————–
—————————————————————————————-
|   0 | SELECT STATEMENT     |       |      1 |        |      1 |00:01:32.27 |    2339K|
|   1 |  SORT AGGREGATE      |       |      1 |      1 |      1 |00:01:32.27 |    2339K|
|*  2 |   FILTER             |       |      1 |        |    709K|00:01:32.13 |    2339K|
|*  3 |    TABLE ACCESS FULL | SALES |      1 |      1 |   1554K|00:00:00.67 |   13571 |
|   4 |    SORT AGGREGATE    |       |    173 |      1 |    173 |00:01:30.73 |    2326K|
|*  5 |     TABLE ACCESS FULL| SALES |    173 |      1 |   2131K|00:01:30.44 |    2326K|
—————————————————————————————-

1 VS 2131k 差无数倍

   1 – SEL$1
   3 – SEL$1 / A@SEL$1
   4 – SEL$2
   5 – SEL$2 / B@SEL$2

使用  hint

select /*+UNNEST(@"SEL$2")*/ count(*) from sales a where amount_sold >
( select avg(amount_sold)  from sales b
where b.prod_id = a.prod_id
and channel_id = 3 and promo_id = 999 )
and channel_id = 3 and promo_id = 999 ;  
select * from table(dbms_xplan.display_cursor(NULL,NULL,'allstats last')) ;

Plan hash value: 4009253081

———————————————————————————-
| Id  | Operation             | Name    | Starts | E-Rows | A-Rows |   A-Time   |

PLAN_TABLE_OUTPUT
———————————————————————————-
———————————————————————————-
|   0 | SELECT STATEMENT      |         |      1 |        |      1 |00:00:01.64 |
|   1 |  SORT AGGREGATE       |         |      1 |      1 |      1 |00:00:01.64 |
|*  2 |   HASH JOIN           |         |      1 |      2 |    709K|00:00:01.64 |
|   3 |    VIEW               | VW_SQ_1 |      1 |      1 |     72 |00:00:00.85 |
|   4 |     HASH GROUP BY     |         |      1 |      1 |     72 |00:00:00.85 |
|*  5 |      TABLE ACCESS FULL| SALES   |      1 |     48 |   1554K|00:00:00.44 |
|*  6 |    TABLE ACCESS FULL  | SALES   |      1 |     48 |   1554K|00:00:00.44 |
———————————————————————————-

看完上述内容,你们掌握Oracle11g/12c dbms_stat extended stats 实验的示例分析的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/123893.html

(0)

相关推荐

  • 怎么设置vivado中ip核的位置(vivado怎么打开查看端口的窗口)

    技术Vivado中IP是如何控制端口的可见与不可见Vivado中IP是如何控制端口的可见与不可见,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。测试平台Viv

    攻略 2021年12月22日
  • 孩子生在美国,去美国生子孩子有必要吗

    技术孩子生在美国,去美国生子孩子有必要吗想要顺利去美国生宝宝,具有关键性的一部是办理签证,只有拿到签证才能进入美国孩子生在美国。当然了,美国的签证也有很多种类,可分为移民签证和非移民签证两种,非移民签证主要为“短期”或“

    生活 2021年10月23日
  • 如何理解rman中的incarnation

    技术如何理解rman中的incarnation如何理解rman中的incarnation,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。inc

    攻略 2021年11月30日
  • oracle中数据泵dump文件存放nfs报ORA-27054错误怎么办

    技术oracle中数据泵dump文件存放nfs报ORA-27054错误怎么办小编给大家分享一下oracle中数据泵dump文件存放nfs报ORA-27054错误怎么办,相信大部分人都还不怎么了解,因此分享这篇文章给大家参

    攻略 2021年11月20日
  • 刷墙面漆步骤,房子的墙面怎么刷涂料,详细步骤

    技术刷墙面漆步骤,房子的墙面怎么刷涂料,详细步骤墙面刷涂料的粉刷大致分为以下几个步骤:1.处理墙面基层刷墙面漆步骤;2.涂刷界面剂;3.防水处理;4.刮腻子;5.砂纸打磨;6.刷油漆。 1. 处理墙面基层
    墙面基层处理

    生活 2021年10月25日
  • qq空白昵称代码复制,王者荣耀战队名空白代码

    技术qq空白昵称代码复制,王者荣耀战队名空白代码在王者荣耀中显示空白名字的原理的是输入一些游戏无法显示的字符即可qq空白昵称代码复制,所以想取空白名字只要输入一些奇葩字符就可以了。不过王者荣耀最新官方规定游戏中不能出现空

    生活 2021年10月30日