达梦8统计信息收集

本文介绍了达梦数据库的统计信息收集策略,包括对象分类、采样率确定、直方图生成、静态与动态收集时机、全模式和小表/大表收集建议,以及查看和调整统计信息的方法,以帮助管理员优化查询性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、统计信息简介

     对象统计信息描述了对象数据的分布特征。统计信息是优化器的代价计算的依据,可以帮助优化器较精确地估算成本,对执行计划的选择起着至关重要的作用。统计信息的收集频率是一把双刃剑,频率太低导致统计信息滞后,频率太高又影响查询性能,因此,系统管理员需要根据实际情况,合理安排统计信息收集的频率。

2、统计信息对象

    达梦数据库的统计数据对象分三种:表统计信息、列统计信息和索引统计信息。统计信息生成过程分三个步骤:

1. 确定采样的对象:根据数据对象,确定需要分析哪些数据。

1) 表:计算表的行数、所占的页数目、平均记录长度。

2) 列:统计列数据的分布特征。

3) 索引:统计索引列的数据分布特征。

2. 确定采样率。用户根据统计数据对象的大小,确定采样率。如缺省,则默认通过内部算法确定数据的采样率。

3. 生成统计信息。根据不同的数据对象生成不同的统计信息。

1)表:表的行数、所占的页数目、平均记录长度等汇总数据。

2)列和索引:将采样的数据按照不同的分布特征生成相应的直方图。有两种类型的直方图:频率直方图和等高直方图。根据算法分析表的数据分布特征(以不同值的数据量 1万个为分界线),确定直方图的类型。频率直方图的每个桶(保存统计信息的对象)的高度不同,等高直方图每个桶的高度相同。生成直方图时,如果不同值少于 1 万个则用频率直方图,否则用等高直方图。

3、收集统计信息时机

收集统计信息的时机有两种:一是在查询之前进行静态收集;二是在查询的同时进行动态收集。

静态收集是在查询之前完成。和查询操作互不干涉,因此不影响查询性能。

动态收集是在查询的过程中完成。具体为在构造查询计划阶段进行,统计信息收集完成之后再继续构造计划,因此会影响计划阶段性能,特别是在高并发场景中。

从性能角度考虑,推荐用户使用静态收集。

4、统计信息收集建议

4.1 全模式收集

    制定月度收集计划,进行全模式收集,语句如下:

DBMS_STATS.GATHER_SCHEMA_STATS('用户名',100,TRUE,'FOR ALL COLUMNS SIZE AUTO',1,'GLOBAL');

4.2 小表收集方式

对于数据量不大,收集统计信息耗时短的表,建议在更新统计信息时,由开发人员配合梳理数据量每天变化比较大的表,进行全表收集,按照表数据量排序,第一和最后一个、第二和倒数第二这样的规则来组合收集,可以减少一次性全部收集占用的时间,提高效率。

  1. 查询条件都是按天进行筛选,这样的查询所涉及的表建议每天导入数据以后收集。
收集语句如下:

DBMS_STATS.GATHER_TABLE_STATS('模式名','表名',null,100,TRUE,'FOR ALL COLUMNS SIZE AUTO',1,'GLOBAL');

以如下两个表为例。

call SP_CREATE_JOB('统计信息收集',1,0,'',0,0,'',0,'');

call SP_JOB_CONFIG_START('统计信息收集');

call SP_ADD_JOB_STEP('统计信息收集', '统计信息收集语句', 0, 'DBMS_STATS.GATHER_TABLE_STATS(''模式名'',''表名'',null,100,TRUE,''FOR ALL COLUMNS SIZE AUTO'',1,''GLOBAL'');

DBMS_STATS.GATHER_TABLE_STATS(''模式名'',''表名'',null,100,TRUE,''FOR ALL COLUMNS SIZE AUTO'',1,''GLOBAL'');', 0, 0, 0, 0, NULL, 0);

call SP_ADD_JOB_SCHEDULE('统计信息收集', '统计信息收集时间', 1, 1, 1, 0, 0, '22:00:00', NULL, '2023-07-27 09:45:17', NULL, '');

call SP_JOB_CONFIG_COMMIT('统计信息收集');

4.3 大表收集方式

4.3.1 全列收集

初次迁移完成,对于允许统计信息收集时间短,并且需要收集统计信息的大表,选择跑存储过程,以列为单位进行收集,可以有效缩短统计信息收集时间。

收集脚本如下:

--更新指定表的所有列的统计信息可使用sysdba或者用户自身

--DROP TABLE stat_history;

--SELECT * FROM stat_history;

create table stat_history (beg_time TIMESTAMP,end_time timestamp,sql_str varchar2(500),table_name varchar2(200),col_name VARCHAR2(200));

declare --更新所有列的统计信息

v_sql varchar(4000);

v_begtime VARCHAR2(200);

v_endtime varchar2(200);

CURSOR c1 IS SELECT

  SCH.NAME AS SCHEMA_NAME,

        TAB.NAME AS TABLE_NAME ,

        SYSCOL.NAME AS COLUMN_NAME

FROM

        SYSOBJECTS AS TAB,

        SYSOBJECTS AS SCH,

        SYSCOLUMNS AS SYSCOL

WHERE

        SCH.ID =TAB.SCHID

    AND TAB.ID =SYSCOL.ID

    AND SCH.NAME in ('ABCD')   --填写实际用户名

    AND SYSCOL.TYPE$ NOT IN ('BLOB','CLOB','TEXT')

    and TAB.NAME  IN(select  TABLE_NAME  from ALL_TABLES WHERE OWNER in ('ABCD'));  --填写实际用户名

 begin

  for i in c1

  loop     v_sql:='DBMS_STATS.GATHER_TABLE_STATS('''||i.SCHEMA_NAME||''','''||i.TABLE_NAME||''',null,100,TRUE,''FOR COLUMNS “'||i.COLUMN_NAME||'” SIZE AUTO'',1,''GLOBAL'');';   

--v_sql:='stat 100 on '||i.SCHEMA_NAME||'.'||i.TABLE_NAME||'("'||i.COLUMN_NAME||'");';

  --print v_sql;

  v_begtime := sysdate();

  execute immediate v_sql;

  v_endtime :=sysdate();

  insert into stat_history VALUES (v_begtime,v_endtime,v_sql,i.TABLE_NAME,i.COLUMN_NAME);

  commit;

  end loop;

end;

如上面脚本收集统计信息时间较长,可根据表中数据量将数据量较大的表拆分出来,编写多个脚本并行执行,可有效提高收集效率。收集脚本如下:

--更新指定表的所有列的统计信息可使用sysdba或者用户自身

--DROP TABLE stat_history;

--SELECT * FROM stat_history;

create table stat_history (beg_time TIMESTAMP,end_time timestamp,sql_str varchar2(500),table_name varchar2(200),col_name VARCHAR2(200));

declare --更新所有列的统计信息

v_sql varchar(4000);

v_begtime VARCHAR2(200);

v_endtime varchar2(200);

CURSOR c1 IS SELECT

  SCH.NAME AS SCHEMA_NAME,

        TAB.NAME AS TABLE_NAME ,

        SYSCOL.NAME AS COLUMN_NAME

FROM

        SYSOBJECTS AS TAB,

        SYSOBJECTS AS SCH,

        SYSCOLUMNS AS SYSCOL

WHERE

        SCH.ID =TAB.SCHID

    AND TAB.ID =SYSCOL.ID

    AND SCH.NAME in ('ABCD')   --填写实际用户名

    AND SYSCOL.TYPE$ NOT IN ('BLOB','CLOB','TEXT')

    and TAB.NAME  IN(select  TABLE_NAME  from ALL_TABLES WHERE OWNER in ('ABCD') AND TABLE_NAME IN ('TABLE_NAME'));  --填写实际用户名和表名

 begin

  for i in c1

  loop     v_sql:='DBMS_STATS.GATHER_TABLE_STATS('''||i.SCHEMA_NAME||''','''||i.TABLE_NAME||''',null,100,TRUE,''FOR COLUMNS “'||i.COLUMN_NAME||'” SIZE AUTO'',1,''GLOBAL'');';   

--v_sql:='stat 100 on '||i.SCHEMA_NAME||'.'||i.TABLE_NAME||'("'||i.COLUMN_NAME||'");';

  --print v_sql;

  v_begtime := sysdate();

  execute immediate v_sql;

  v_endtime :=sysdate();

  insert into stat_history VALUES (v_begtime,v_endtime,v_sql,i.TABLE_NAME,i.COLUMN_NAME);

  commit;

  end loop;

end;

4.3.2 部分列统计信息收集

若不具备4.1和4.2统计信息收集的时间条件,可选择收集部分列的统计信息,包括表的索引列和条件列。

对于索引列和SQL语句所涉及的条件列,需要查出来以后,添加到统计信息收集语句中。

--条件列统计信息收集

普通表:

stat 100 on 用户名.表名(列名1,列名2);

分区表:

DBMS_STATS.GATHER_TABLE_STATS('用户名','表名',null,100,TRUE,'FOR COLUMNS 列名 SIZE AUTO',1,'GLOBAL');

5、查看统计信息

--用于经过 GATHER_TABLE_STATS、GATHER_INDEX_STATS 或 GATHER_SCHEMA_STATS 收集之后展示。

dbms_stats.table_stats_show('模式名','表名');

--用于经过 GATHER_TABLE_STATS、GATHER_INDEX_STATS 或 GATHER_SCHEMA_STATS 收集之后展示。 返回两个结果集:一个是索引的统计信息;另一个是直方图的统计信息。

dbms_stats.index_stats_show('模式名','索引名');

–用于经过 GATHER_TABLE_STATS、GATHER_INDEX_STATS 或 GATHER_SCHEMA_STATS 收集之后展示。

dbms_stats.COLUMN_STATS_SHOW('模式名','表名','列名');

更多统计信息收集方式参考达梦在线服务平台:

https://eco.dameng.com/document/dm/zh-cn/ops/performance-optimization#5.1%20%E7%BB%9F%E8%AE%A1%E4%BF%A1%E6%81%AF%E6%A6%82%E8%BF%B0

6、一般情况收集建议

量体裁衣,找到适合自己系统的统计信息收集策略,用尽量小的代价收集到能稳定跑出正确执行计划的统计信息即可。也就是说统计信息不一定要特别准,只要有代表性,足够跑出正确执行计划就可以了。

根据实际业务情况以及经验,对统计信息的收集建议从如下几个维度考虑:

1)对于数据量小的库,全库统计信息收集时间短,并且不会影响到跑批业务,可按月进行全库收集;

2)按照表的数据变化量进行收集,数据变化量超过30%进行收集;

3)收集变更频率高的表;

4)分批次按照数据量大小组合收集,数据量大的表和数据量小的表进行组合收集,尽量保持每组收集的时间差距不大;

5)从业务角度对使用感受影响明显的表;

6)可以设置多个作业并行进行,对多个用户,多个Table。

统计信息收集语句如下:

DBMS_STATS.GATHER_TABLE_STATS('USERNAME','RISK_WARNED_INSTITUTION',null,100,TRUE,'FOR ALL COLUMNS SIZE AUTO',1,'GLOBAL');  

<think>首先,用户的问题是:“请问达梦数据库 单表 统计分析 方法”。用户想知道在达梦数据库中如何对单个表进行统计分析。 从系统指令中,我需要: - 使用中文回答。 - 结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠。 - 使用$...$格式表示行内数学表达式,$$...$$格式表示独立公式。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,如[^1]。 参考站内引用: - 引用[1]:讨论达梦数据库的多表查询,强调性能优化、避免函数调用、确保数据完整性和SQL语法正确性。 - 引用[2]:描述如何通过重建表来处理表空间占用过大的问题,包括创建备份表、锁定表、插入数据、截断原表、重新插入数据等步骤。 用户的问题是关于单表的统计分析,所以我需要专注于单表查询和数据统计的方法。 关键点: - 统计分析可能包括计算行数、平均值、最大值、最小值、总和等聚合函数。 - 在达梦数据库中,这些可以通过SQL语句实现,使用SELECT语句结合聚合函数。 - 性能优化很重要,因为统计操作可能消耗资源。 结构化回答: 1. **介绍单表统计分析的基本方法**:使用SQL聚合函数。 2. **详细步骤**:解释如何编写SQL查询。 3. **性能优化建议**:基于引用[1]和[2],提到优化措施。 4. **常见错误和解决方法**:参考引用[1]。 5. **生成相关问题**:在最后添加相关问题。 使用数学表达式: - 例如,在解释聚合函数时,使用$...$格式表示数学概念,如$count(*)$、$avg(column)$等。 - 如果有公式,如方差公式,使用$$...$$格式。 添加引用标识: - 当引用站内内容时,在末尾添加[^1]或[^2]。 回答结构: - 开头:简要介绍单表统计分析。 - 主体: - 基本SQL语句示例。 - 优化技巧。 - 常见问题解决。 - 结尾:总结。 - 然后添加相关问题。 相关问题生成: - 基于用户的问题,生成3-5个相关问题,如优化方法、应用场景等。 确保真实性: - 达梦数据库是基于SQL的,类似于Oracle,所以SQL语法类似。 - 聚合函数包括COUNT, SUM, AVG, MAX, MIN等。 - 性能优化:使用索引、避免全表扫描等。 最终回答大纲: 1. 解释单表统计分析的概念。 2. 提供SQL示例。 3. 讨论优化和常见错误。 4. 添加引用标识。 5. 生成相关问题。</think>### 达梦数据库单表统计分析方法 在达梦数据库中,单表统计分析是指对单个数据表进行数据汇总、计算聚合指标(如行数、平均值、最大值等)的过程。这有助于数据质量检查、性能监控或业务决策。达梦数据库使用标准SQL语法实现统计分析,类似于其他关系型数据库。以下是逐步说明: #### 1. **基本SQL统计方法** - 使用`SELECT`语句结合聚合函数执行统计分析。常用聚合函数包括: - `COUNT(*)`:计算表中总行数,例如:$count(*)$ - `SUM(column)`:计算数值列的总和,例如:$sum(x)$ - `AVG(column)`:计算数值列的平均值,例如:$avg(x) = \frac{sum(x)}{count(x)}$ - `MAX(column)` 和 `MIN(column)`:获取列的最大值和最小值。 - `GROUP BY`:如需分组统计,但单表分析通常无需分组。 示例SQL查询: ```sql -- 计算表的总行数、某列的平均值和最大值 SELECT COUNT(*) AS total_rows, AVG(salary) AS avg_salary, MAX(age) AS max_age FROM employee; ``` 此查询会输出`employee`表的行数、`salary`列的平均值和`age`列的最大值。注意替换`employee`、`salary`和`age`为实际表名和列名。 #### 2. **性能优化建议** - **索引使用**:在统计列上创建索引可加速聚合查询。例如,对频繁统计的列(如`sales_amount`)添加索引: ```sql CREATE INDEX idx_sales ON sales(sales_amount); ``` 索引能减少全表扫描,提升查询速度[^1]。 - **避免函数调用**:在聚合函数中避免嵌套复杂函数,以免降低性能。例如,优先使用`AVG(column)`而非`AVG(ABS(column))`[^1]。 - **表空间管理**:如果表数据量过大(如超过GB级),统计分析可能变慢。参考引用[2]的重建表方法减少碎片: - 先创建备份表并锁定原表。 - 转移数据后截断原表(`TRUNCATE TABLE`)。 - 重新插入数据并提交。 这能优化存储结构,加速后续统计操作[^2]。 - **估算统计**:对大表,使用近似统计函数(如`APPROX_COUNT_DISTINCT`)代替精确计算,以减少资源消耗。 #### 3. **常见错误及解决方法** - **错误1:查询超时或性能低下** - **原因**:表数据量过大或未优化索引。 - **解决**:使用`EXPLAIN PLAN`分析查询执行计划,添加索引或分区表。如果空间占用过高,参考引用[2]的重建表流程[^2]。 - **错误2:聚合结果不准确** - **原因**:数据包含NULL值或数据类型不匹配(如对字符串列使用`SUM`)。 - **解决**:在查询前清理数据(如`WHERE column IS NOT NULL`),并确保列类型为数值型。 - **错误3:语法错误** - **原因**:SQL语法错误,如缺少括号或错误别名。 - **解决**:使用达梦的`SQLCHECK`工具验证语法,或参考官方文档[^1]。 #### 4. **最佳实践** - **事务处理**:在统计操作期间,建议锁定表(`LOCK TABLE ... IN EXCLUSIVE MODE`)以避免并发修改导致数据不一致[^2]。 - **工具辅助**:达梦提供`DBMS_STATS`包收集统计信息(如行数、列分布),用于优化器决策: ```sql EXEC DBMS_STATS.GATHER_TABLE_STATS('schema_name', 'table_name'); ``` - **资源监控**:使用达梦性能视图(如`V$SESSION`)监控查询资源占用,确保不影响其他操作。 通过以上方法,您可以高效完成单表统计分析。达梦数据库的优化措施(如索引和表重建)能显著提升性能,尤其在大数据场景下[^1][^2]。 ### 相关问题 1. 如何在达梦数据库中优化大表的统计查询性能? 2. 达梦数据库的聚合函数有哪些高级用法? 3. 单表统计分析在数据仓库中有哪些应用场景? 4. 如何处理达梦数据库统计查询中的NULL值问题?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值