用dbms_stats收集统计信息

CBO优化器基于三个方面评估SQL cost:selectivity,cardinality and cost(CPU&MEM&I/O),利用dbms_stats收集column柱状图信息,CBO依据柱状图可以得到column的数据分布情况:

 

SQL> create table t1 as select 1 c1,rpad('*',200,'*') c2 from all_objects;

 

Table created.

 

SQL> insert into t1 values(2,rpad('*',200,'*'));

 

1 row created.

 

SQL> commit;

 

Commit complete.

 

SQL> create index idx_t1_01 on t1(c1);

 

Index created.

 

SQL> select * from user_tab_histograms where table_name = 'T1' and column_name='C1' order by 4;

 

no rows selected

 

SQL> select table_name,

  2         column_name,

  3         num_distinct,

  4         num_nulls,

  5         num_buckets,

  6         density,

  7         low_value,

  8         high_value

  9    from user_tab_col_statistics

 10   where table_name = 'T1'

 11     and column_name = 'C1';

 

no rows selected

 

SQL> explain plan for select * from t1 where c1=1;

 

Explained.

 

SQL> select * from table(dbms_xplan.display());

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

Plan hash value: 3617692013

 

--------------------------------------------------------------------------

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |      | 76264 |  8564K|   558   (1)| 00:00:07 |

|*  1 |  TABLE ACCESS FULL| T1   | 76264 |  8564K|   558   (1)| 00:00:07 |

--------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

 

   1 - filter("C1"=1)

 

Note

-----

   - dynamic sampling used for this statement

 

17 rows selected.

SQL> explain plan for select * from t1 where c1=2;

 

Explained.

 

SQL> select * from table(dbms_xplan.display());

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------------------------------

Plan hash value: 3018735338

 

-----------------------------------------------------------------------------------------

| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |

-----------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT            |           |     1 |   115 |     2   (0)| 00:00:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| T1        |     1 |   115 |     2   (0)| 00:00:01 |

|*  2 |   INDEX RANGE SCAN          | IDX_T1_01 |     1 |       |     1   (0)| 00:00:01 |

-----------------------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------------------------------

---------------------------------------------------

 

   2 - access("C1"=2)

 

Note

-----

   - dynamic sampling used for this statement

 

18 rows selected.

 

没有收集统计信息时的计划是正确的,FTS for 1,index for 2;

 

现在收集统计信息:

 

SQL> exec dbms_stats.gather_table_stats(ownname => user,tabname => 'T1',method_opt => 'for all columns');

 

PL/SQL procedure successfully completed.

 

SQL> select * from user_tab_histograms where table_name = 'T1' and column_name='C1' order by 4;

 

TABLE_NAME   COLUMN_NAME   ENDPOINT_NUMBER ENDPOINT_VALUE ENDPO

------------ ------------- --------------- -------------- -----

T1           C1                       5584              1

 

 

SQL> select table_name,

  2         column_name,

  3         num_distinct,

  4         num_nulls,

  5         num_buckets,

  6         density,

  7        utl_raw.cast_to_number(low_value) low_value,

  8        utl_raw.cast_to_number(high_value) high_value

  9    from user_tab_col_statistics

 10   where table_name = 'T1'

 11     and column_name = 'C1';

 

TABLE_NAME   COLUMN_NAME   NUM_DISTINCT  NUM_NULLS NUM_BUCKETS    DENSITY LOW_VALUE HIGH_VALUE

------------ ------------- ------------ ---------- ----------- ---------- --------- ----------

T1           C1                       2          0           1 7.2698E-06      1.00       2.00

 

SQL> explain plan for select * from t1 where c1=2;

 

Explained.

 

SQL> select * from table(dbms_xplan.display());

 

PLAN_TABLE_OUTPUT

----------------------------------------------------------------------------------

Plan hash value: 3617692013

 

--------------------------------------------------------------------------

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |      | 33872 |  6747K|   558   (1)| 00:00:07 |

|*  1 |  TABLE ACCESS FULL| T1   | 33872 |  6747K|   558   (1)| 00:00:07 |

--------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

PLAN_TABLE_OUTPUT

----------------------------------------------------------------------------------

 

   1 - filter("C1"=2)

 

13 rows selected.

 

SQL>

这样的收集没有显示出数据的倾斜度,结果得出了错误的计划;

 

重新收集:

 

 

SQL> exec dbms_stats.gather_table_stats(ownname => user,tabname => 'T1',estimate_percent=>100,method_opt => 'FOR COLUMNS SIZE 5 c1');

 

PL/SQL procedure successfully completed.

 

SQL> exec dbms_stats.gather_index_stats(ownname => user,indname => 'IDX_T1_01');

 

PL/SQL procedure successfully completed.

 

SQL> select * from user_tab_histograms where table_name = 'T1' and column_name='C1' order by 4;

 

TABLE_NAME   COLUMN_NAME   ENDPOINT_NUMBER ENDPOINT_VALUE ENDPO

------------ ------------- --------------- -------------- -----

T1           C1                      67742              1

T1           C1                      67743              2

 

SQL>

SQL> explain plan for select * from t1 where c1=1;

 

Explained.

 

SQL> select * from table(dbms_xplan.display());

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------------

Plan hash value: 3617692013

 

--------------------------------------------------------------------------

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |      | 67742 |  6946K|   558   (1)| 00:00:07 |

|*  1 |  TABLE ACCESS FULL| T1   | 67742 |  6946K|   558   (1)| 00:00:07 |

--------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------------

 

   1 - filter("C1"=1)

 

13 rows selected.

 

SQL> explain plan for select * from t1 where c1=2;

 

Explained.

 

SQL> select * from table(dbms_xplan.display());

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------------

Plan hash value: 3018735338

 

-----------------------------------------------------------------------------------------

| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |

-----------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT            |           |     1 |   105 |     2   (0)| 00:00:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| T1        |     1 |   105 |     2   (0)| 00:00:01 |

|*  2 |   INDEX RANGE SCAN          | IDX_T1_01 |     1 |       |     1   (0)| 00:00:01 |

-----------------------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------------

---------------------------------------------------

 

   2 - access("C1"=2)

 

14 rows selected.

 

SQL>

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/45259/viewspace-662126/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/45259/viewspace-662126/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`DBMS_STATS.GATHER_TABLE_STATS` 是 Oracle 数据库中一个过程(procedure),用于收集表的统计信息。它可以替代旧版的 `ANALYZE TABLE` 语句,提供更高效和更精确的统计信息收集方法。 使用 `DBMS_STATS.GATHER_TABLE_STATS` 可以收集表的各种统计信息,包括行数、块数、列的分布等。这些统计信息对于优化查询性能非常重要,因为它们可以帮助优化器生成更准确的执行计划。 以下是使用 `DBMS_STATS.GATHER_TABLE_STATS` 收集统计信息的示例: ```sql BEGIN DBMS_STATS.GATHER_TABLE_STATS( ownname => 'schema_name', tabname => 'table_name', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO', cascade => TRUE ); END; ``` 在上面的示例中,`schema_name` 是表所属的模式名,`table_name` 是要收集统计信息的表名。`estimate_percent` 参数控制了采样的百分比,使用 `DBMS_STATS.AUTO_SAMPLE_SIZE` 可以自动选择合适的采样大小。`method_opt` 参数指定了统计信息收集的方法和选项,'FOR ALL COLUMNS SIZE AUTO' 表示对所有列进行统计,并自动选择合适的大小。`cascade` 参数表示是否同时收集相关索引的统计信息。 需要注意的是,`DBMS_STATS.GATHER_TABLE_STATS` 还有其他可选的参数,可以根据具体需求进行设置,如 `granularity`、`degree` 等。详细的参数说明可以参考 Oracle 官方文档。 通过使用 `DBMS_STATS.GATHER_TABLE_STATS`,可以更灵活地、更高效地收集表的统计信息,并提升查询性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值