我们在收集列的统计信息与直方图时,往往都是对某一列的收集。当谓词使用多个相关列时,会导致约束条件的冗余。这几个相关的列也被称作关联列。出现这种情况时,查询优化器也会做出不准确的判断。所以我们必须对这些相关列收集统计信息或直方图来描述这种依赖关系。

幸运的是,从Oracle11g开始,数据库可以收集基于表达式或者一组列上的对象统计信息和直方图,从而解决这种问题。这种新的统计叫做扩展的统计信息(extension statistics)。

这种技术实际上是基于表达式或一组列创建一个隐藏列,叫做扩展(extension),再在扩展列上收集统计信息与直方图。

一、如何定义扩展列

可以调用Oracle自带的包dbms_stats的函数create_extended_stats来实现。下面对测试表的相关列做扩展列。测试表语句参见《Oracle中收集表与列统计信息》(http://www.linuxidc.com/Linux/2013-12/93503.htm)一个基于表达式upper(pad),另一个基于val2和val3组成的列组。在测试表里,val2和val3取值相同,高度关联。

SELECT DBMS_STATS.CREATE_EXTENDED_STATS(OWNNAME  => 'TEST',
TABNAME => 'T',
EXTENSION => '(upper(pad))'),
DBMS_STATS.CREATE_EXTENDED_STATS(OWNNAME => 'TEST',
TABNAME => 'T',
EXTENSION => '(val2,val3)')
FROM DUAL;

这样就定义了两个扩展列。他们分别是基于表达式的和基于多列的。

二、如何查询扩展列信息

基于user_stat_extensions、dba_stat_extensions和all_stat_extensions,都能查询相关的扩展列信息。

SELECT COLUMN_NAME, DATA_TYPE, HIDDEN_COLUMN, DATA_DEFAULT
FROM USER_TAB_COLS
WHERE TABLE_NAME = 'T'; COLUMN_NAME DATA_TYPE HID DATA_DEFAULT
---------------------------------------- ---------- --- ----------------------------------------
ID NUMBER NO
VAL1 NUMBER NO
VAL2 NUMBER NO
VAL3 NUMBER NO
PAD VARCHAR2 NO
SYS_STU0KSQX64#I01CKJ5FPGFK3W9 VARCHAR2 YES UPPER("PAD")
SYS_STUPS77EFBJCOTDFMHM8CHP7Q1 NUMBER YES SYS_OP_COMBINED_HASH("VAL2","VAL3")

从data_default这列我们可以观察到,SYS_OP_COMBINED_HASH("VAL2","VAL3"),扩展列统计使用了哈希函数,所以val2和val3只有使用相等(=)谓词时,优化器才使用扩展统计信息。

二、如何删除扩展统计信息

依然使用Oracle自带的dbms_stats提供的过程drop_extended_stats来删除扩展统计信息。

BEGIN
DBMS_STATS.DROP_EXTENDED_STATS(OWNNAME => 'TEST',
TABNAME => 'T',
EXTENSION => '(upper(pad))');
DBMS_STATS.DROP_EXTENDED_STATS(OWNNAME => 'TEST',
TABNAME => 'T',
EXTENSION => '(val2,val3)');
END;

最后提一下,扩展统计信息是基于Oracle11g的另一个新特性——虚拟列。它并不存储数据,那它有什么现实意义呢?我们可以设想,在开发代码中,有很多sql语句用到了upper(varchar2)、trunc(date),此时尽管在这些列上建立索引,执行计划依然不会走索引,为了避免全表扫描,我们最好的方法是改写语法,谓词尽量不被函数转换,但有时候在不好转换语句时,可以创建一个虚拟列,然后在虚拟列上建立索引。比如下面的方法:

CREATE TABLE persons(
NAME VARCHAR2(100),
name_upper AS (UPPER(NAME)));

如果在频繁查询使用了upper(name)=’MIKE’,就可以使用name_upper=’MIKE’,前提是虚拟列建立索引。当然虚拟列也不不好的地方,比如插入数据不能指定所有列,因为虚拟列是不存数据的。

Oracle扩展的统计信息的更多相关文章

  1. Oracle的自动统计信息不收集直方图的信息

    Oracle的自动统计信息不收集直方图的信息 在oracle9i中,默认的统计信息收集是不收集直方图信息的,也就是说默认的MOTHOD_OPT模式为FOR ALL COLUMNS SIZE 1 在10 ...

  2. Oracle之自动收集统计信息

    一.Oracle 11g 在Oracle的11g版本中提供了统计数据自动收集的功能.在部署安装11g Oracle软件过程中,其中有一个步骤便是提示是否启动这个功能(默认是启用这个功能). 在这里介绍 ...

  3. 关于Oracle开启自动收集统计信息的SPA测试

    主题:关于Oracle开启自动收集统计信息的SPA测试 环境:Oracle RAC 11.2.0.4(Primary + Standby) 需求:生产Primary库由于历史原因关闭了自动统计信息的收 ...

  4. Oracle重新获取统计信息以及SQLSERVER重建索引

    Oracle重新获取统计信息 exec dbms_stats.gather_schema_stats(ownname =>'LCoe739999',options => 'GATHER', ...

  5. Oracle性能优化之Oracle里的统计信息

    一.什么是统计信息 oracle数据库里的统计信息是如下的一组数据:他们存储在数据字典里,且从多个维度描述了oracle数据库数据对象的详细信息. oracle数据库里的统计信息主要分为以下6种情况: ...

  6. 基于Oracle的SQL优化(崔华著)-整理笔记-第5章“Oracle里的统计信息”

    第5章“Oracle里的统计信息” 详细介绍了Oracle数据库里与统计信息相关的各个方面的内容,包括 Oracle数据库中各种统计信息的分类.含义.收集和查看方法,以及如何在Oracle数据库里正确 ...

  7. oracle里的统计信息

    1 oracle里的统计信息 Oracle的统计信息是这样的一组数据,存储在数据字典,从多个维度描述了oracle数据库对象的详细信息,有6种类型 表的统计信息:记录数.表块的数量.平均行长度等 索引 ...

  8. Oracle 分区表的统计信息实例

    ORACLE的统计信息在执行SQL的过程中扮演着非常重要的作用,而且ORACLE在表的各个层次都会有不同的统计信息,通过这些统计信息来描述表的,列的各种各样的统计信息.下面通过一个复合分区表来说明一些 ...

  9. Oracle 手动收集统计信息

    收集oracle统计信息 优化器统计范围: 表统计: --行数,块数,行平均长度:all_tables:NUM_ROWS,BLOCKS,AVG_ROW_LEN: 列统计: --列中唯一值的数量(NDV ...

随机推荐

  1. Oracle创建表空间、表、一级用户授权

    ---恢复内容开始--- 1. 安装: 百度一下你就知道 2. sqlplus登录/sqlplus命令登录 在安装Oracle时,你需要记住设置的“全局数据库名”(默认为orcl) 和 口令,在以两种 ...

  2. 博客系统(cnblog)

    1.用户表:Userinfo 2.博客站点表:Blog 3.标签表:Tag 4.分类表:Category 5.文章表:Article 6.点赞踩表:ArticelUpDown 7.评论表:Commen ...

  3. python学习笔记之paramiko和sqlalchemy (第九天)

    参考银角大王 :http://www.cnblogs.com/wupeiqi/articles/5095821.html http://www.cnblogs.com/wupeiqi/articles ...

  4. Git 教程(四):标签和其他

    标签管理 发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本.将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来.所以,标签也是版本库 ...

  5. 2018-2019-2 20165215《网络对抗技术》Exp4 恶意代码分析

    目录 实践目标 实践内容 基础问题回答 实验步骤 使用schtasks指令监控系统 使用sysmon工具监控系统 使用VirusTotal分析恶意软件 使用PEiD进行外壳检测 使用PE explor ...

  6. drf 单表

    ^_^ # [{title,price},{}] 构造的数据结构 简单的FBV/CBV def showbooks(request): # FBV if request.method =='GET': ...

  7. oracle密码过期问题解决

    1.查看open用户 select username,account_status,expiry_date,profile from dba_users; 2.查看目前密码过期策略 select * ...

  8. JS中if判断 非空即为真 非0即为真

    1.字符串参与判断时:非空即为真判断字符串为空的方法if(str!=null && str!=undefined && str !='')可简写为if(!str){   ...

  9. [转]SQL中 OVER(PARTITION BY) 取上一条,下一条等

    OVER(PARTITION BY)函数介绍 开窗函数               Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个组返 ...

  10. linux awk用法

    awk是一个强大的文本分析工具,在对数据进行分析并生成报告时显得尤为强大. 使用方法:awk [options]  'BEGIN{ commands } pattern{ commands } END ...