Oracle 11g怎么收集多列统计信息

73次阅读
没有评论

共计 3188 个字符,预计需要花费 8 分钟才能阅读完成。

这篇文章主要介绍“Oracle 11g 怎么收集多列统计信息”,在日常操作中,相信很多人在 Oracle 11g 怎么收集多列统计信息问题上存在疑惑,丸趣 TV 小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Oracle 11g 怎么收集多列统计信息”的疑惑有所帮助!接下来,请跟着丸趣 TV 小编一起来学习吧!

        通常,当我们将 SQL 语句提交给 Oracle 数据库时,Oracle 会选择一种最优方式来执行,这是通过查询优化器 Query Optimizer 来实现的。CBO(Cost-Based Optimizer)是 Oracle 默认使用的查询优化器模式。在 CBO 中,SQL 执行计划的生成,是以一种寻找成本(Cost)最优为目标导向的执行计划探索过程。所谓成本(Cost)就是将 CPU 和 IO 消耗整合起来的量化指标,每一个执行计划的成本就是经过优化器内部公式估算出的数字值。

        我们在写 SQL 语句的时候,经常会碰到 where 子句后面有多个条件的情况,也就是根据多列的条件筛选得到数据。默认情况下,oracle 会把多列的选择率(selectivity)相乘从而得到 where 语句的选择率,这样有可能造成选择率(selectivity)不准确,从而导致优化器做出错误的判断。为了能够让优化器做出准确的判断,从而生成准确的执行计划,oracle 在 11g 数据库中引入了收集多列统计信息。本文通过对测试表的多条件查询,介绍收集多列统计信息的重要性。

1. 环境准备

我们在 Oracle 11g 中进行试验。

此处)折叠或打开

SQL

SQL explain plan for select * from hoegh where employee_id=110 and email=\ JCHEN\

Explained.

SQL

SQL select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

——————————————————————————–

Plan hash value: 774871165

—————————————————————————

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

—————————————————————————

| 0 | SELECT STATEMENT | | 1 | 69 | 8 (0)| 00:00:01 |

|* 1 | TABLE ACCESS FULL| HOEGH | 1 | 69 | 8 (0)| 00:00:01 |

—————————————————————————

Predicate Information (identified by operation id):

—————————————————

PLAN_TABLE_OUTPUT

——————————————————————————–

 1 – filter(\ EMPLOYEE_ID\ =110 AND \ EMAIL\ =\ JCHEN\)

13 rows selected.

SQL

从执行计划可以看出返回了 1 行记录,而事实又是什么样的呢?我们执行一下这条 sql 语句。

点击 (此处) 折叠或打开

SQL select count(*) from hoegh where employee_id=110 and email=\ JCHEN\

 COUNT(*)

———-

 16

SQL

由此看出,测试表 hoegh 符合查询条件的数据有 16 行,而执行计划提示的只有 1 行,出错了。这是怎么回事呢,也就是我们在开篇提到的选择率(selectivity)出了问题。
在这个多列条件查询语句中,选择率=1/107*1/107,返回行数=1/107*1/107*1712=16/107 1;由于表中存在符合条件的记录,并且返回行数不可能小于 1,所以 Oracle 返回了 1。

5. 收集多列统计信息,再次查看两个条件的 where 语句的执行计划

点击 (此处) 折叠或打开

SQL

SQL exec dbms_stats.gather_table_stats(\ HR\ ,\ HOEGH\ ,method_opt= \ for columns(employee_id,email)\

PL/SQL procedure successfully completed.

SQL

SQL explain plan for select * from hoegh where employee_id=110 and email=\ JCHEN\

Explained.

SQL select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

——————————————————————————–

Plan hash value: 774871165

—————————————————————————

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

—————————————————————————

| 0 | SELECT STATEMENT | | 16 | 1152 | 8 (0)| 00:00:01 |

|* 1 | TABLE ACCESS FULL| HOEGH | 16 | 1152 | 8 (0)| 00:00:01 |

—————————————————————————

Predicate Information (identified by operation id):

—————————————————

PLAN_TABLE_OUTPUT

——————————————————————————–

 1 – filter(\ EMPLOYEE_ID\ =110 AND \ EMAIL\ =\ JCHEN\)

13 rows selected.

SQL

从执行计划的结果来看,同样的一条 sql 查询语句,在收集多列统计信息后,Oracle 的选择率(selectivity)由错变对,这是由于 sql 语句中的两个条件是有关联的,即 employee_id 和 email 在 employees 表中都是唯一的,都可以唯一标识一行记录;而在收集多列统计信息之前,Oracle 并不知道这两个查询条件有关联,所以在计算选择率(selectivity)时,只是简单地采取了相乘的方法。

到此,关于“Oracle 11g 怎么收集多列统计信息”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注丸趣 TV 网站,丸趣 TV 小编会继续努力为大家带来更多实用的文章!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-18发表,共计3188字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)