共计 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 小编会继续努力为大家带来更多实用的文章!