百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 优雅编程 > 正文

查询效率慢,那你是不会分析!第二章

sinye56 2024-10-10 11:03 6 浏览 0 评论

何时手动收集统计信息

有时候自动收集统计并不合适,因为自动收集统计信息是在午夜运行的,然而由于对象是在白天被修改了,导致导致的统计信息变得陈旧,这里有2种这类对象:

· 白天经常被delete,或者truncated之后又rebuild的表(经常变化的表)

· 批量操作之后有10%或者以上的数据被更改的表(批量处理的表)

· 对于经常变化的表,可以将其统计信息设置为null,当ORACLE遇到一个表没有统计信息,ORACLE会动态采样以便为查询优化器收集必要的统计信息。动态采样这个特征受到参数optimizer_dynamic_sampling的控制,它的默认值为2,同时呢optimizer_mode也能控制动态采样,可将其设置为all.

以SCOTT用户下的DEPT表为例,将一个表的统计信息设置为null的方法如下:

BEGIN DBMS_STATS.DELETE_TABLE_STATS('SCOTT','DEPT');

DBMS_STATS.LOCK_TABLE_STATS('SCOTT','DEPT');

END;/

我们也可以在表具有典型的,代表性的时候收集统计信息,并且锁住其统计信息,因为在夜晚自动收集的统计信息未必适用于白天的负载,而典型的统计信息具有代表意义,所以这个时候采取lock其典型的统计信息更能让CBO选择更优的执行计划。

至于上面的两种方法用哪种,这个还需要根据业务,实际情况分析之。

· 对于批量处理的表 ,应该在批量处理完成的时候立即对其收集统计信息,可以将收集统计信息的脚本绑定到批量处理的脚本中。

· 对于外部表,只能通过gather_table_stats过程来收集统计信息,并且外部表不支持取样,所以需要把gather_table_stats中的estimate_percent设置为null。

· 系统的统计信息也需要手动收集,因为这些信息是不会自动收集的。

· 对于固定对象,比如说动态性能表,需要手动的执行gather_fixed_objects_stats过程来收集。固定的对象反映了当前数据库的活动。当数据库活动处于具有代表性的时候,就应该收集这类统计信息。

锁住/解锁统计信息

· LOCK_SCHEMA_STATS

· LOCK_TABLE_STATS

· UNLOCK_SCHEMA_STATS

· UNLOCK_TABLE_STATS

手动收集统计信息

· 如果你选择手动收集统计信息,那么你需要手动的收集所有用户的统计信息,包括系统用户。

如果你数据库中的数据是有规律的变化的,那么你可以有规律的收集统计信息,以便统计信息能够准确的反映数据库中的对象的特征。

· 可以利用DBMS_STATS包,来收集表,索引,列,以及分区表的统计信息,DBMS_STATS不能收集CLUSTER 的统计信息,不过可以收集单个表来代替收集整个CLUSTER的统计信息。

· 当你收集表,列,索引的统计信息的时候,如果ORACLE在数据字典中发现这个对象已经收集了统计信息,那么ORACLE会更新已经存在的统计信息,旧的统计信息会被保存下来,如果你愿意还能还原旧的统计信息。

· 你可以使用DBMS_STATS.GATHER_DICTIONARY_STATS来收集系统用户的统计信息,这个过程收集所有的系统用户的统计信息,包括SYS和SYSTEM,以及其他用户,比如CTXSYS,DRSYS。

· 当数据库对象的统计信息被更新之后,ORACLE会使已经解析的SQL语句作废,当再次运行该SQL语句的时候,ORACLE会重新解析该SQL,优化器会自动的根据新的统计信息选择一条新的执行计划。对于分布式的数据库,不会作废。

· 收集统计信息的过程

o GATHER_INDEX_STATS --收集索引统计信息

o GATHER_TABLE_STATS --收集表,列,索引统计信息

o GATHER_SCHEMA_STATS --收集schema所有对象统计信息

o GATHER_DICTIONARY_STATS –-收集所有系统用户的统计信息

o GATHER_DATABASE_STATS --收集数据库所有对象统计信息

· 我们利用上面的过程收集统计信息的时候有几个需要关心的参数

o 采样

o 并行

o 分区

o 列统计以及直方图/柱状图

o 过期的统计

o 自定义统计

在收集统计信息的操作过程中我们可以使用采样来评估统计信息。采样对于收集统计信息来说是一项很重要的技术。如果在收集统计信息的时候不使用采样,那么就需要对表进行全表扫描,以及排序整个表。通过采样可以降低收集必要的统计信息所花费的资源。

控制采样的参数是ESTIMATE_PERCENT,采样的参数可以设置任意值(当然要在范围内),不过ORACLE公司推荐设置ESTIMATE_PERCENT为DBMS_STATS.AUTO_SAMPLE_SIZE。

AUTO_SAMPLE_SILE可以让ORACLE自己决定最好的采样值,因为不同类型(table,index,column)的统计信息有不同的需求。采样的例子:

EXEC DBMS_STATS.GATHER_SCHEMA_STATS(‘SCOTT’,DBMS_STATS.AUTO_SAMPLE_SIZE);

当ESTIMATE_PERCENT参数是手动指定的,如果手动指定的参数过小,不能收集到足够的信息,那么DBMS_STATS可能会自动增长ESTIMATE_PERCENT的值,这样就能确保收集到足够的统计信息。

我们既可以串行的收集统计信息,也可以并行的收集统计信息。参数DEGREE控制DBMS_STATS是否使用并行特征。ORACLE公司推荐将DEGREE参数设置为DBMS_STATS.AUTO_DEGREE。这样设置过后,ORACLE就能够根据OBJECT的SIZE,以及与并行有关的init参数来决定一个恰当的并行度,收集统计信息。注意:cluster index,domain index,bitmap join index不能使用并行特征。

对于分区表和分区索引,DBMS_STATS既可以单独的收集分区统计信息,也可以收集整个表/索引的统计信息。对于组合分区,DBMS_STATS也能够收集子分区,分区,以及整个表/索引的统计信息。参数GRANULARITY控制分区统计信息的收集。因为分区统计信息,全局统计信息对于大多数系统来说都是非常重要的,所以ORACLE公司推荐将其设置为AUTO来收集分区,以及全局的统计信息。

当对表收集统计信息的时候,DBMS_STATS会收集列的数据分布信息。数据分布最基本的统计信息就是这个列的最大值与最小值。如果这一列是倾斜的,那么优化器仅仅根据列最大值与最小值是无法制定出准确的执行计划的。对于倾斜的数据分布,我们可以收集列的直方图/柱状图统计信息,这样可以让优化器制定出更加准确的执行计划。

参数METHOD_OPT控制柱状图的收集。ORACLE公司推荐设置METHOD_OPT为FOR ALL COLUMNS SIZE AUTO。这样设置过后ORACLE会自动的判断哪一列需要收集柱状图,并且自动的设置柱状图的bucket。你同样可以手动的设置哪一列需要收集柱状图,以及柱状图的bucket。

为了知道统计信息是否过期,ORACLE提供了表监控功能。将init参数STATISTICS_LEVEL设置为ALL或者TYPICAL(默认),就开启了表监控的功能(10g已经不需要alter table monitor了)。表监控功能跟踪表的insert,update,delete,truncate,操作,并且记录在DBA_TAB_MODIFICATIONS视图里面。我们在查询DBA_TAB_MODIFICATIONS视图的时候有可能查询不到结果,或者查询的结果不准确,这个时候需要用DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO过程将内存中的信息刷新到

该视图中。OPTIONS参数设置为GATHER STALE或者GATHER AUTO,就会让DBMS_STATS判断表的统计信息是否过期(注意GATHER_TABLE_STATS中没有这个参数,只有GATHER_DATABASE_STATS,GATHER_SCHEMA_STATS过程中有这个参数)。判断表的统计信息是否过期的依据是是否有10%以上的数据被修改过,如果被修改过了,那么ORACLE就认为之前的统计信息过期了,ORACLE会重新收集统计信息。

在我们创建了函数索引之后,我们要为列收集统计信息,这个时候我们需要设置参数METHOD_OPT为FOR ALL HIDDEN COLUMNS。

收集统计信息的策略

通常情况下,我们会将ORACLE自动收集统计信息功能给关闭,我们会采用手动的方式给数据库收集统计信息。至于收集统计信息的策略需要根据系统来确定。下面说说几种常见的情况:

· 如果你系统中的表的数据是增量(有规律)的增加,也就是说你几乎不做任何的批量处理操作,比如批量删除,批量加载操作。对于这样的表收集统计信息是非常简单的。你可以通过查看DBA_TAB_MODIFICATIONS视图来观察表的变化情况,观察表中数据量的变化是否超过了10%,并且记录下天数。这样你就可以每隔这样的时间间隔对其收集一次统计信息。你可以用CRONTAB,或者JOB调用GATHER_SCHEMA_STATS或者GATHER_TABLE_STATS过程来收集统计信息。

· 对于经常批量操作的表,那么表的统计信息就必须在批量操作之后对其收集统计信息。

· 对于分区表,通常只有一个分区被修改,这种情况下可以只收集单独分区的统计信息,不过收集整个表的统计信息还是非常有必要的

收集统计信息的一些例子

对表收集统计信息

BEGIN

DBMS_STATS.GATHER_TABLE_STATS(ownname => 'SCOTT',

tabname => 'DEPT',

estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,

method_opt => 'for all columns size repeat',

degree => DBMS_STATS.AUTO_DEGREE,

cascade=>TRUE

);

END;

/

上面的例子收集SCOTT.DEPT表的统计信息。这里面值得关注的一个参数就是method_opt。这个参数控制是否收集列的直方图信息。通常情况下,是不会收集直方图的,关于直方图不是三言两语可以说明白的。它的四个选项method_opt=>'for all columns size skewonly'

ORACLE会根据数据分布收集直方图

method_opt=>'for all columns size repeat'

只有以前收集过直方图,才会收集直方图信息,所以一般我们会设置method_opt 为repeat

method_opt=>'for all columns size auto'

ORACLE会根据数据分布以及列的workload来确定是否收集直方图

method_opt=>'for all columns size interger'

我们自己指定一个bucket值

相关推荐

Linux基础知识之修改root用户密码

现象:Linux修改密码出现:Authenticationtokenmanipulationerror。故障解决办法:进入单用户,执行pwconv,再执行passwdroot。...

Linux如何修改远程访问端口

对于Linux服务器而言,其默认的远程访问端口为22。但是,出于安全方面的考虑,一般都会修改该端口。下面我来简答介绍一下如何修改Linux服务器默认的远程访问端口。对于默认端口而言,其相关的配置位于/...

如何批量更改文件的权限

如果你发觉一个目录结构下的大量文件权限(读、写、可执行)很乱时,可以执行以下两个命令批量修正:批量修改文件夹的权限chmod755-Rdir_name批量修改文件的权限finddir_nam...

CentOS「linux」学习笔记10:修改文件和目录权限

?linux基础操作:主要介绍了修改文件和目录的权限及chown和chgrp高级用法6.chmod修改权限1:字母方式[修改文件或目录的权限]u代表所属者,g代表所属组,o代表其他组的用户,a代表所有...

Linux下更改串口的权限

问题描述我在Ubuntu中使用ArduinoIDE,并且遇到串口问题。它过去一直有效,但由于可能不必要的原因,我觉得有必要将一些文件的所有权从root所有权更改为我的用户所有权。...

Linux chown命令:修改文件和目录的所有者和所属组

chown命令,可以认为是"changeowner"的缩写,主要用于修改文件(或目录)的所有者,除此之外,这个命令也可以修改文件(或目录)的所属组。当只需要修改所有者时,可使用...

chmod修改文件夹及子目录权限的方法

chmod修改文件夹及子目录权限的方法打开终端进入你需要修改的目录然后执行下面这条命令chmod777*-R全部子目录及文件权限改为777查看linux文件的权限:ls-l文件名称查看li...

Android 修改隐藏设置项权限

在Android系统中,修改某些隐藏设置项或权限通常涉及到系统级别的操作,尤其是针对非标准的、未在常规用户界面显示的高级选项。这些隐藏设置往往与隐私保护、安全相关的特殊功能有关,或者涉及开发者选项、权...

完蛋了!我不小心把Linux所有的文件权限修改了!在线等修复!

最近一个客户在群里说他一不小心把某台业务服务器的根目录权限给改了,本来想修改当前目录,结果执行成了根目录。...

linux改变安全性设置-改变所属关系

CentOS7.3学习笔记总结(五十八)-改变安全性设置-改变所属关系在以前的文章里,我介绍过linux文件权限,感兴趣的朋友可以关注我,阅读一下这篇文章。这里我们不在做过的介绍,注重介绍改变文件或者...

Python基础到实战一飞冲天(一)--linux基础(七)修改权限chmod

#07_Python基础到实战一飞冲天(一)--linux基础(七)--修改权限chmod-root-groupadd-groupdel-chgrp-username-passwd...

linux更改用户权限为root权限方法大全

背景在使用linux系统时,经常会遇到需要修改用户权限为root权限。通过修改用户所属群组groupid为root,此操作只能使普通用户实现享有部分root权限,普通用户仍不能像root用户一样享有超...

怎么用ip命令在linux中添加路由表项?

在Linux中添加路由表项,可以使用ip命令的route子命令。添加路由表项的基本语法如下:sudoiprouteadd<network>via<gateway>这...

Linux配置网络

1、网卡名配置相关文件回到顶部网卡名命名规则文件:/etc/udev/rules.d/70-persistent-net.rules#PCIdevice0x8086:0x100f(e1000)...

Linux系列---网络配置文件

1.网卡配置文件在/etc/sysconfig/network-scripts/下:[root@oldboynetwork-scripts]#ls/etc/sysconfig/network-s...

取消回复欢迎 发表评论: