暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

AI播客学SQL系列5.8: 给数据库装上“GPS”:一文讲透优化器统计信息

67
本文是基于笔者墨天轮专栏课程《Oracle降龙十八掌之SQL性能诊断和调优》生成的AI播客和PPT课件,希望对大家有所帮助和提供一点儿价值,同时欢迎大家订阅原课程。
解读数据库优化器统计信息,表、列、索引、系统等四大类统计信息及其作用。探讨统计信息的收集方式、过期风险及重收集时机,分析不准确统计信息对执行计划的危害,并介绍直方图类型、采样率调整、锁定机制及分布式处理要点
今天咱们要聊的这个话题特别有意思——数据库优化器统计信息。
你知道吗,这就像是给数据库装上了"GPS导航",告诉它哪条路最快、哪条路最堵。
没错!优化器统计信息可以说是SQL执行计划优化的DNA了。
没有这些信息,数据库就像个盲人开车,完全靠猜怎么走最快。
哈哈,这个比喻很形象!那具体来说,这些统计信息都包括些什么呢?
嗯,主要是四大块。
首先是表统计信息,这个就像是房子的基本信息——有多少间房、每间房多大、有几个空着的。
具体来说就是行数、数据块数、行平均长度这些。
哦,那列统计信息呢?这个听起来像是房间里住的是什么人?
对,你这个比喻不错!列统计信息关注的是每列的具体特征。
比如说某个列有多少个不同的值、最小值是多少、最大值是多少,还有平均值、空值数量等等。
这些东西对于判断该用哪种索引特别重要。
索引统计信息又是什么呢?是不是就是索引这栋楼的电梯系统好不好用?
哈哈,你这个理解很妙!确实,索引统计信息主要就是描述索引的结构效率。
比如B树的高度——楼层越少查找越快;叶子块数量越多说明数据量越大;还有聚类因子,这个指标特别关键,它衡量的是索引顺序和表数据物理顺序的匹配程度。
呃,聚类因子这个概念我得好好理解一下。
就是说如果索引顺序和表里数据存放顺序很一致,那扫描起来就快,对吧?
完全正确!聚类因子低意味着索引顺序和表数据物理顺序接近,顺序扫描效率高;反之,如果聚类因子很高,数据库可能就不愿意用索引了。
还有就是直方图统计信息,这个就像是把住户按年龄、职业分类,让查询优化器知道数据不是均匀分布的。
说到这儿,我想起了系统统计信息这个概念。
这个是不是就像是整个城市的交通状况报告?
是的,系统统计信息关注的就是整个数据库服务器的资源状况,主要是CPU性能和I/O速度。
这些信息会直接影响优化器对不同执行路径成本的评估。
嗯,听起来这些统计信息真的很重要。
但问题是,这些信息是怎么收集的?总不能是数据库自己凭空编出来的吧?
当然不是。
这些信息是通过专门的统计信息收集过程采集的,结果会存放在数据字典里。
我们可以通过像DBA_TABLE_STATISTICS、DBA_TAB_COLUMNS这些数据字典视图来查看。
那在实际使用中,如果统计信息不准会有什么问题呢?
这可不是小事!统计信息不准确可能导致优化器做出错误的执行计划选择。
比如说,如果表里有1000万行数据,但统计信息显示只有1万行,优化器可能会选择全表扫描而不是索引查找。
哎呀,那性能差距可就太大了!
而且这里有个概念叫"过期统计信息"。
如果表数据变化超过10%,统计信息就会被标记为STALE。
这时候数据库虽然还能用旧统计信息,但效果肯定大打折扣。
那什么时候需要重新收集统计信息呢?总不能天天都收集吧?
确实不能太频繁。
通常建议在以下几种情况下收集:
  • 一是数据量发生显著变化,比如大批量导入导出后;
  • 二是应用上线前;
  • 三是性能出现问题时;
  • 四是定期维护,比如每周或每月一次。
嗯,那在排查性能问题时,应该怎么检查统计信息呢?
第一步通常是确认统计信息是否存在。
有时候新创建的表可能还没有统计信息。
然后要看最后更新时间是不是很久以前了。
另外要检查是否过期了,就是前面说的STALE状态。
还有没有其他需要注意的地方?
还有一个很重要的点是要看采样大小是不是足够。
如果表很大但只采了很小一部分样本来估计统计信息,准确性就会受影响。
还有就是要检查数据是否发生了大规模的波动,比如是否进行了批量数据导入或删除操作。
对,还有直方图这个东西。
我看到有些统计信息里有FREQUENCY、HEIGHT BALANCED这些类型,这些都是干什么用的?
直方图类型决定了如何描述数据分布。
  • FREQUENCY直方图适用于每个桶包含大致相同数量的值;
  • HEIGHT BALANCED直方图则是所有桶的高度差不多;
  • HYBRID是两者的混合;
  • TOP-FREQUENCY则重点关注出现频率最高的值。
    选择合适的直方图类型对优化器做出正确决策很关键。
说到这里,我想问问,如果优化器统计信息真的导致了性能问题,一般怎么解决?
最直接的解决方案就是重新收集统计信息。
可以使用DBMS_STATS包来手动收集。
比如收集单个表的统计信息可以用DBMS_STATS.GATHER_TABLE_STATS。
那收集的时候有没有什么参数可以调整的?
当然有。
最主要的参数就是采样率
采样率越高,统计信息越准确,但代价也越大。
还要注意收集范围,可以是整个表、分区表的一个分区,甚至是只收集索引统计信息而不收列统计信息。
哦对了,你刚才提到了锁定的统计信息。
这个是干什么用的?
STATTYPE_LOCKED这个字段表示统计信息是否被锁定。
有时候为了避免业务高峰期统计信息被意外更改,DBA可能会暂时锁定统计信息。
被锁定的统计信息不会被自动收集或更新。
嗯,看来统计信息的管理还挺复杂的。
那在分布式环境里,统计信息是怎么处理的?
分布式环境更复杂一些。
每个数据库实例都会维护自己的统计信息,但对于全局查询,需要考虑所有相关实例的统计信息汇总。
有些数据库支持全局统计信息的收集和管理。
确实如此。
而且现在很多现代数据库都有自动统计信息收集功能,但自动收集不一定总能满足特定业务场景的需求,所以DBA还是要了解这些机制,知道什么时候需要手动干预。
说得对!好了,今天关于优化器统计信息的分享就到这里。
希望通过这次讨论,大家对数据库的"导航系统"有了更深的理解。记住,好的统计信息才能带来好的执行计划,好的执行计划才能带来快的查询速度。
好,今天的分享就到这里。感谢大家的收听,我们下期再见!

文章转载自SQL和数据库技术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论