SQL优化(二)统计信息

news2024/12/25 9:33:13

收集统计信息 

数据库的统计信息非常重要,如果没有正确地收集表的统计信息,或者没有及时地更新表的统计信息,SQL就有可能走错执行计划,也就会出现性能问题。

统计信息主要分为表的统计信息、列的统计信息、索引的统计信息、系统的统计信息、数据字典的统计信息以及动态性能视图基表的统计信息,我们主要关注表、列、索引的统计信息。

注:本文涉及到的数据库版本为Oracle Database 19c Enterprise Edition Release

表的统计信息 

表的统计信息主要包含表的总行数(num_rows)​、表的块数(blocks)以及行平均长度(avg_row_len)​,通过查询数据字典DBA_TABLES获取表的统计信息。

假设现在我们队FSBZDJ这张表进行统计,可以用以下语句查询统计信息:

 select owner, table_name, num_rows, blocks, avg_row_len
     from dba_tables
     where owner = 'WODEV' --表所属账户
     and table_name = 'FSBZDJ'; --表名

如果是新建的表,可能没有收集过统计信息,有可能查出来是空的,执行下面的存储过程进行收集。 

BEGIN
DBMS_STATS.GATHER_TABLE_STATS(
            ownname             => 'WODEV',--表所属账户
            tabname             => 'FSBZDJ',--表名
            estimate_percent    => 100,--采样率,小表100%即可,超大表可以部分采样
            method_opt          => 'for all columns size auto',--控制直方图收集策略
            no_invalidate       => FALSE,
            degree              => 1,--根据表大小,CPU资源和负载设置
            cascade             => TRUE
);
END;

 

通过查询结果,可以看出该表总数据行数6916行,1016个数据块,平均行长度为777字节。 

列的统计信息

列的统计信息主要包含列的基数、列中的空值数量以及列的数据分布情况(直方图)​。可以通过数据字典DBA_TAB_COL_STATISTICS查看列的统计信息。

可以通过以下语句收集FSBZDJ的列信息:

 select column_name, num_distinct, num_nulls, num_buckets, histogram
    from dba_tab_col_statistics
    where owner = 'WODEV'
    and table_name = 'FSBZDJ';

由于列数过多,只展示部分列。 

NUM_BUCKETS代表直方图的桶数,HISTOGRAM代表直方图类型。

可以用下列语句一起查出基数,选择性等指标。 

select a.column_name,
           b.num_rows,
          a.num_nulls,
          a.num_distinct Cardinality,--基数
          round(a.num_distinct / b.num_rows * 100, 2) selectivity,--选择性
          a.histogram,--直方图类型
          a.num_buckets
      from dba_tab_col_statistics a, dba_tables b
     where a.owner = b.owner
      and a.table_name = b.table_name
      and a.owner = 'WODEV'
      and a.table_name = 'FSBZDJ';

索引的统计信息

集群因子 

集群因子是索引的一个统计属性,用于判断索引回表需要消耗的物理I/O次数

集群因子的计算跟ROWID有关。

可以用以下语句查询FSBZDJ这个表下IDX_FSBZDJ_DJBH索引的集群因子

 select owner, index_name, clustering_factor
     from dba_indexes
     where owner = 'WODEV'
     and index_name = 'IDX_FSBZDJ_DJBH';

 

集群因子的计算需要查出rowid,然后相邻行间作比较 

select * from 
(select fsbzdj_djbh,rowid from fsbzdj order by fsbzdj_djbh)  
where rownum<10

 

首先我们比较1、2行对应的ROWID是否在同一个数据块,如果在同一个数据块,CLUSTERING_FACTOR+0;如果不在同一个数据块,那么CLUSTERING_FACTOR+1。

然后我们比较2、3对应的ROWID是否在同一个数据块,如果在同一个数据块,CLUSTERING_FACTOR+0;如果不在同一个数据块,那么CLUSTERING_FACTOR+1。

再比较3、4对应的ROWID是否在同一个数据块,如果在同一个数据块,CLUSTERING_FACTOR+0;如果不在同一个数据块,那么CLUSTERING_FACTOR+1。

一直这样有序地比较下去,直到比较完索引中最后一个键值,由此可知

集群因子的值介于表的块数和表行数之间

计算sql如下:

 select sum(case when block#1 = block#2 and file#1 = file#2 then 0
              else 1 end) CLUSTERING_FACTOR
      from (select 
    dbms_rowid.rowid_relative_fno(rowid) file#1,
    lead(dbms_rowid.rowid_relative_fno(rowid), 1, null) over(order by fsbzdj_djbh) file#2,
    dbms_rowid.rowid_block_number(rowid) block#1,
    lead(dbms_rowid.rowid_block_number(rowid), 1, null) over(order by fsbzdj_djbh) block#2
    
    from fsbzdj
    where fsbzdj_djbh is not null
    );

 

计算结果与统计的结果接近,不是完全相等因为表的统计信息没有实时更新。

如果集群因子与块数接近,说明表的数据基本上是有序的,而且其顺序基本与索引顺序一样。这样在进行索引范围或者索引全扫描的时候,回表只需要读取少量的数据块就能完成。

如果集群因子与表记录数接近,说明表的数据和索引顺序差异很大,在进行索引范围扫描或者索引全扫描的时候,回表会读取更多的数据块。 

集群因子只会影响索引范围扫描(INDEX RANGE SCAN)以及索引全扫描(INDEX FULL SCAN)​,因为只有这两种索引扫描方式会有大量数据回表。

FSBZDJ这个表块数是1016个块,表行数为6916,集群因子为5184,更接近表的行数 ,说明表的数据和索引顺序差异很大,如果SQL执行中发生回表,将会有严重的性能影响。

索引的统计信息 

索引的统计信息主要包含索引blevel(索引高度-1)​、叶子块的个数(leaf_blocks)以及集群因子(clustering_factor)​。可以通过数据字典DBA_INDEXES查看索引的统计信息。

创建索引的时候会自动收集索引的统计信息,可以用以下SQL收集统计信息。

--查询某个索引
select  blevel, leaf_blocks, clustering_factor,status
     from dba_indexes
     where owner = 'WODEV'
     and index_name = 'IDX_FSBZDJ_DJBH';


--单独收集某个索引的统计信息
BEGIN
      DBMS_STATS.GATHER_INDEX_STATS(ownname => 'WODEV',
                                    indname => 'IDX_FSBZDJ_DJBH');
END;

 

统计用的数据库函数

DBMS_STATS.GATHER_TABLE_STATS

BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(
            ownname          => 'TAB_OWNER',
            tabname          => 'TAB_NAME',
            estimate_percent => 根据表大小设置,
            method_opt       => 'for all columns size repeat',
            no_invalidate    => FALSE,
            degree           => 根据表大小,CPU资源和负载设置,
            granularity      => 'AUTO',
            cascade          => TRUE);
END;

ownname代表表的所属账户,tabname代表表名。

estimate_percent代表采样率,范围是0.000001~100。

一般对小于1GB的表进行100%采样,因为表很小,即使100%采样速度也比较快。有时候小表有可能数据分布不均衡,如果没有100%采样,可能会导致统计信息不准。

对表大小在1GB~5GB的表采样50%,对大于5GB的表采样30%。如果表特别大,有几十甚至上百GB,我们建议应该先对表进行分区,然后分别对每个分区收集统计信息。

采样率不要低于30%。查看某个表采样率用以下SQL:

SELECT owner,
       table_name,
       num_rows,
       sample_size,
       round(sample_size / num_rows * 100) estimate_percent --采样率
     FROM DBA_TAB_STATISTICS
    WHERE owner='WODEV' AND table_name='FSBZDJ';

method_opt用于控制收集直方图策略。

='for all columns size 1' 表示所有列都不收集直方图。

='for all columns size skewonly'  表示对表中所有列收集自动判断是否收集直方图,实际很少使用。

='for all columns size auto'(参数默认值) 表示对出现在where条件中的列自动判断是否收集直方图。

='for all columns size repeat' 表示当前有哪些列收集了直方图,现在就对哪些列收集直方图。

='for columns 列名 size skewonly' 表示单独对该列收集直方图,其余列之前如果收集过直方图,本次也继续收集直方图。

no_invalidate表示共享池中涉及到该表的游标是否立即失效,默认值为DBMS_STATS.AUTO_INVALIDATE,表示让Oracle自己决定是否立即失效。建议将no_invalidate参数设置为false,立即失效。

degree表示收集统计信息的并行度,默认为NULL。如果表没有设置degree,收集统计信息的时候后就不开并行;如果表设置了degree,收集统计信息的时候就按照表的degree来开并行。可以查询DBA_TABLES.degree来查看表的degree,一般情况下,表的degree都为1。

granularity表示收集统计信息的粒度,该选项只对分区表生效,默认为AUTO,表示让Oracle根据表的分区类型自己判断如何收集分区表的统计信息。数据库默认采用AUTO方式。

cascade表示在收集表的统计信息的时候,是否级联收集索引的统计信息,默认值为DBMS_STATS.AUTO_CASCADE,表示让Oracle自己判断是否级联收集索引的统计信息。一般将其设置为TRUE,在收集表的统计信息的时候,级联收集索引的统计信息。

查看表的统计信息是否过期

如果表中有大量数据发生变化,这时表的统计信息就过期了,需要重新收集表的统计信息,如果不重新收集,可能会导致执行计划走错。Oracle数据库中,表中只要有超过10%的数据发生变化,统计信息就会过期。

查询统计信息是否过期:

 begin
    dbms_stats.flush_database_monitoring_info;--刷新数据库监控信息
 end;

 select owner, table_name , object_type, stale_stats, last_analyzed
     from dba_tab_statistics
     where owner = 'WODEV'
     and table_name = 'FSBZDJ';

STALE_STATS为NO代表没过期,如果是YES代表过期。

如果过期了需要重新收集统计信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2123130.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TeamTalk数据库代理服务器

文章目录 main函数主流程关键步骤线程池redis缓存未读消息计数未读消息计数-单聊未读消息计数-群聊 群成员管理 main函数主流程 关键步骤 初始化epoll 线程池数据入口 reactor CProxyConn::HandlePduBuf异步task任务封装&#xff0c;把任务放入线程池&#xff1b;线程池里的…

【AI学习】AI科普:专有名词介绍

这里是阿川的博客&#xff0c;祝您变得更强 ✨ 个人主页&#xff1a;在线OJ的阿川 &#x1f496;文章专栏&#xff1a;AI入门到进阶 &#x1f30f;代码仓库&#xff1a; 写在开头 现在您看到的是我的结论或想法&#xff0c;但在这背后凝结了大量的思考、经验和讨论 目录 1.AI序…

TCP通信三次握手、四次挥手

前言 前面我说到了&#xff0c;UDP通信的实现&#xff0c;但我们经常说UDP通信不可靠&#xff0c;是因为他只会接收和发送&#xff0c;并不会去验证对方收到没有&#xff0c;那么我们说TCP通信可靠&#xff0c;就是因为他会进行验证接收端是否能够接收和发送&#xff0c;并且只…

给大家推荐好用的AI网站

地址&#xff1a;https://ai.ashuiai.com/auth/register?inviteCode8E8DIC1QCR 个人觉得挺好用的&#xff0c;可以免费&#xff0c;免费有限制次数&#xff0c;也可以会员升级200永久免费&#xff0c;我用的200永久免费。 可以在国内使用以下ai模型 回答问题更智能&#xff…

计算机毕业设计 校内跑腿业务系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

分享6个我喜欢的常用网站,来看看有没有你感兴趣的!

分享6个我自己很喜欢的常用网站&#xff0c;平时工作生活中经常会打开&#xff0c;来看看有没有你感兴趣的&#xff01; 1.Crazygames crazygames.com/ 一个超赞的在线小游戏平台&#xff0c;上面有超过7000种游戏任你选。不管你喜欢冒险、解谜、闯关&#xff0c;还是装扮、赛…

概要设计例题

答案&#xff1a;A 知识点&#xff1a; 概要设计 设计软件系统的总体结构&#xff1a;采用某种方法&#xff0c;将一个复杂的系统按照功能划分成模块&#xff1b;确定每个模块的功能&#xff1b;确定模块之间的调用关系&#xff1b;确定模块之间的接口&#xff0c;即模块之间…

返工(Rework)与返修(Repair)有何不一样

IATF 16949 汽车业质量管理体系,以客户需求为基础,组织透过相关单位了解客户需求后,向内部流程展开,目的是确保从研发到出货每个环节都能满足客户需求,同时管控制造过程的效率及良率,使产线能够稳定及准时交货给客户。 IATF 16949 条文中,针对「返工(Rework)」与「返修(…

linux工具的使用

1.yum和apt的概念与使用 yum 和 apt 是两种不同的包管理工具&#xff0c;用于在 Linux 系统上管理软件包。 yum (Yellowdog Updater, Modified) 发行版: 用于基于 RPM 的发行版&#xff0c;如 CentOS、RHEL 和 Fedora。基本命令: 更新包列表: sudo yum update安装包: sudo y…

Sky Takeaway

软件开发整体介绍 软件开发流程 角色分工 软件环境 苍穹外卖 项目介绍 定位&#xff1a;专门为餐饮企业定制的一款软件产品 技术选型 前端环境搭建 阅读readme文档 nginx.exe放入无中文目录运行并启动 后端环境搭建 项目结构 Nginx反向代理 优点 配置 Nginx反向代理 负…

QXlsx编译静态库-配置为Qt模块

Qt读写Excel–QXlsx编译为静态库-配置为Qt模块&#x1f346; 文章目录 Qt读写Excel--QXlsx编译为静态库-配置为Qt模块&#x1f346;[toc]1、概述&#x1f954;2、准备工作&#x1f955;3、配置环境&#x1f33d;4、加载QXlsx静态库&#x1f952; &#x1f449;QXlsx使用&#x…

《深度学习》OpenCV 高阶 图像金字塔 用法解析及案例实现

目录 一、图像金字塔 1、什么是图像金字塔 2、图像金字塔作用 1&#xff09;金字塔尺度间的图像信息补充 2&#xff09;目标检测与识别 3&#xff09;图像融合与拼接 4&#xff09;图像增强与去噪 5&#xff09;图像压缩与编码 二、用法解析 1、向下采样 1&#xff09;概念…

【C++11 ——— 可变参数模板】

C11 ——— 可变参数模板 可变参数模板的概念可变参数模板的定义方式参数包的展开递归式展开参数包逗号表达式展开参数包 emplaceemplace 的使用emplace 的优势 可变参数模板的概念 在C11之前,函数模板和类模板中的模板参数数量是固定的。可变参数模板打破了这个限制,提供了一…

Visual Studio汇编代码高亮与自动补全

高亮插件&#xff1a;AsmDude (可以按照我的颜色进行设置&#xff0c;或者你自己改) 代码自动补全&#xff1a;CodeGeex (功能很多&#xff0c;支持的语言很多)&#xff0c;按Tab补全

Gitea Action注册runner

我的是gitea也可以和github 兼容&#xff0c;只是没有github 那么靓而已 安装一个gitea仓库 docker run -d --name gitea \-p3000:3000 -p2222:22 \-v /git/data:/data \ -v /etc/timezone:/etc/timezone:ro \-v /etc/localtime:/etc/localtime:ro \gitea/gitea:1.21.1setti…

嵌入式实时操作系统(RTOS):原理、应用与发展

摘要&#xff1a;本文围绕嵌入式实时操作系统&#xff08;RTOS&#xff09;展开。首先介绍嵌入式系统与实时操作系统的概念&#xff0c;阐述嵌入式 RTOS 的体系结构。接着分析其关键特性&#xff0c;包含任务管理&#xff08;如任务的创建与删除、调度、同步与通信&#xff09;…

基于SSM架构的农产品朔源系统

项目描述 这是一款基于SSM架构的农产品朔源系统 模块描述 农产品溯源系统 1、农产品管理 农产品列表 新增农产品 2、二维码管理 二维码列表 3、溯源管理 溯源列表 溯源图表 4、 企业管理 设置 添加企业 截图

ts复合流讲解

一、什么是复合流 复合流指的是一条音视频数据流中同时包含了音频ES和视频ES数据&#xff08;ES指的是从编码器出来的音视频裸流比如H264&#xff0c;AAC&#xff09;。在音视频开发中最常见的复合流一般是TS、MP4、flv等。TS和flv一般用于网络传输&#xff0c;MP4一般用于本地…

【区块链 + 人才服务】教育区域初中综合素质评价系统 | FISCO BCOS应用案例

根据国家及相关省份制定的高中阶段学校考试招生制度改革实施意见&#xff0c;全国部分地市将开展初中学生综合素质评 价工作。评价将从思想品德、学业水平、身心健康、艺术素养和社会实践五个维度来记录学生的发展过程。例如&#xff0c; 学生的党团社团活动参与情况、公益活动…

windows手工杀毒-关闭恶意弹窗

上篇回顾&#xff1a;windows手工杀毒-寻找可疑进程之网络连接-CSDN博客 上篇主要介绍了如何通过网络连接发现可疑进程。滥用公认端口的软件可能是可疑软件&#xff0c;因为占用公认端口&#xff0c;可能导致正常服务不能正常使用。可以查询ip或域名的相关情报信息&…