达梦参数配置¶
dm.ini是达梦最基本的配置文件,每创建一个数据库,都会生成一个dm.ini配置文件。dm.ini 是 DM 数据库启动所必须的配置文件,用于设置 DM 数据库服务器的各种功能和性能选项。 主要的配置模块包括:控制文件相关、数据库相关、内存相关、线程相关等。
dmarch.ini及sqllog.ini配置文件分别依赖于dm.ini中的ARCH_INI及SVR_LOG,默认均不开启(默认为0,开启为1)。可使用自动化脚本根据现场环境进行自动优化。
其中参数分手动、静态、动态三类。手动参数无法动态修改,只能修改配置文件重启数据库生效。静态参数可以动态修改,但无法生效,亦需重启生效。
动态参数可以动态修改,修改后立即生效,根据生效范围又分为会话级与系统级。会话级修改后会影响当前会话及后续创建的会话。系统级修改后会影响所有会话。
达梦数据库的参数文件(配置文件)是一个文本文件,保存在数据文件所在目录。
-- 在数据库内部可以使用SQL查看动态视图v$dm_ini来查询参数配置情况
-- 譬如:查看compatible_mode参数。在DM中,这个参数控制着DM对其他关系型数据库(Oracle,MySQL)等的兼容性
SELECT PARA_NAME, PARA_VALUE, PARA_TYPE FROM v$dm_ini WHERE para_name LIKE 'COMPA%';
-- DM数据库的INI参数,都可以通过如下方式查看,在DM达梦数据库中,有3个系统函数可以查看参数配置情况。
-- 分别是SF_GET_PARA_VALUE、SF_GET_PARA_DOUBLE_VALUE和SF_GET_PARA_STRING_VALUE三个函数,分别对应参数值为数值类型、浮点类型、字符串类型的参数时使用。
SF_GET_PARA_VALUE(scope int, paraname varchar(256))
SF_GET_PARA_DOUBLE_VALUE(scope int, paraname varchar(8187))
SF_GET_PARA_STRING_VALUE(scope int, paraname varchar(8187))
-- 其中,SCOPE参数为1表示获取INI文件中配置参数的值,为2表示获取内存中配置参数的值。
-- 示例:查看数据库实例最大连接数,在文件和内存中的配置。达梦数据库安装默认连接数为100,实际项目中可能不够用,如下是修改最大连接数的方法
SELECT SF_GET_PARA_VALUE(2,'MAX_SESSIONS'); -- 先查一下当前最大连接数,看看结果是不是默认的100
-- DM的INI参数都可以通过调用系统过程SP_SET_PARA_VALUE/SP_SET_PARA_DOUBLE_VALUE/SP_SET_PARA_STRING_VALUE的方法来进行修改或设置。
-- SP_SET_PARA_VALUE的作用就是设置 dm.ini 文件中非浮点和字符串类型的参数值
-- 第一个参数:scope:取值为 1、2 。1 表示 dm.ini 文件和内存参数都修改,不需要重启服务器;2 表示只修改 dm.ini 文件,服务器重启后生效。
-- 第二个参数:具体要设置的dm.ini中的参数名
-- 第三个参数:参数值
-- 举例说明:将 dm.ini 文件中 HFS_CACHE_SIZE 参数值设置为 320
SP_SET_PARA_VALUE (1,'HFS_CACHE_SIZE',320);
达梦数据表的数据结构¶
达梦数据库对于行存数据表支持 索引组织表 和 堆表 两种形式,两者的都有rowid列。默认建表是索引组织表。
用于在执行其他索引时快速定位数据(一般业务查询不会以rowid列为查询条件),两种表的区别在于:
- 表采用的存储方式称为索引组织表(index organizedtable),也即 表都是根据主键的顺序来进行组织存放的。
索引组织表:在达梦数据库中的默认的表组织类型,默认以 B+BTREE 的数据结构来存放数据,ROWID列是逻辑值 ,从1开始一直增长,在数据的插入时默认会插入ROWID列值,所以插入速度会受此列影响而变慢,同时也会占用更多的存储空间。ROWID其实就是隐式自增列
当DDL语句未显式创建聚集索引,则默认的会创建一个聚集索引(这个索引由达梦数据库自动维护),其索引键是ROWID,即记录默认以 ROWID在页面中排序。ROWID 是达梦为 B 树为记录生成的逻辑递增序号,表上不同记录的 ROWID 是不一样的,并且最新插入的记录 ROWID 最大。
很多情况下,以 ROWID 建的默认聚集索引并不能提高查询速度,因为实际情况下很少人根据 ROWID来查找数据。
因此,DM 提供三种方式供用户指定聚集索引键:
- CLUSTER PRIMARY KEY:指定列为聚集索引键,并同时指定为主键,称为聚簇主键;
- CLUSTER KEY:指定列为聚集索引键,但是是非唯一的;
- CLUSTER UNIQUE KEY:指定列为聚集索引键,并且是唯一的。
聚集索引和非聚集索引¶
-
主键:主键是一种基于关系模型来定义的逻辑约束。即整个SQL表中,不能存在重复的主键列(一列或多列),主键的作用更侧重于不重复。
-
在达梦数据库中,主键约束是通过创建**唯一索引**来实现的。
-- 通过 CLUSTER 或 NOT CLUSTER 关键字来指明创建索引的类型。 -- CLUSTER 指明该主键是创建在聚集索引上的 -- NOT CLUSTER 指明该主键是创建在非聚集索引上的 -
索引:索引是一种数据结构。比如以某列为聚集索引(即以某列为索引节点构成的 B+BTREE 数据结构),索引的作用更侧重于数据排序。
从物理存储角度进行分类,可分为聚集索引和非聚集索引。
-
聚集索引:整个索引组织表的 B+BTREE 数据结构,都按照索引键来构建的。它定义了数据的物理存储顺序。整个表的物理存储是按照聚集索引键构造一棵 B+ 树,表数据存储在 B+ 树叶子节点上,通过定位索引可直接在 B+ 树中找到数据。每张表有且只有一个聚集索引。
-
非聚集索引:**将二级索引列和聚集索引列共同存储在 B+ 树叶子节点上。如果查找非聚集索引键值或聚集索引键值可直接在 B+ 树中找到;如果查找索引键值以外的数据,则需要回到一级索引中进行查找。**每张表可以有多个非聚集索引。
在关系数据库中,索引和主键是两个概念。只是MySQL中一般把聚集索引和主键做为同义词了,MySQL默认会以主键创建一颗聚集索引树来存储数据。
注意:在达梦中,聚集索引和主键是两个概念,用于不同的目的。
- 主键的作用更侧重于数据不重复。它是传统关系型数据库上设计的逻辑业务需求(唯一)
- 索引的作用更侧重于数据排序。它是定义数据物理上的数据结构。
-- (索引组织表)每个表只有一个聚集索引:二叉树结构只能按照一个索引键来排序
------------------------------------------------------------------------------------------------------------------------
-- DDL (如果仅创建业务字段,达梦内部会自动生成ROWID来做为隐式主键)
CREATE TABLE users(
id BIGINT,
C1 INT,
C2 int,
C3 VARCHAR(20),
C4 VARCHAR(20)
);
-- 查询此表上的索引:可以看到达梦默认会创建一个随机名称的聚集索引。索引类型是CLUSTER
SELECT * FROM DBA_INDEXES idx
WHERE idx.owner='QHDATA_TEST' AND idx.table_name='users';
-- 用户手动在该表添加聚集索引(以id为索引键)后,该默认聚集索引则会自动删除。这个用户创建聚集索引是可以删除的,如果删除后原先的聚集索引会自动恢复。
CREATE CLUSTER INDEX idx_users_id on QHDATA_TEST."users"(id);
-- 如果直接在该表上基于其他表创建聚集索引,则直接覆盖前面的。
CREATE CLUSTER INDEX idx_users_index on QHDATA_TEST."users"(id);
-- 查询此索引的DDL语句
SELECT dbms_metadata.get_ddl(OBJECT_TYPE => 'INDEX',NAME=>upper('idx_users_id'),SCHNAME => 'QHDATA_TEST');
-- 索引DDL语句
CREATE OR REPLACE CLUSTER INDEX "QHDATA_TEST"."idx_users_id" ON "QHDATA_TEST"."users"("id" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
-- 创建基于主键的聚集索引:PRIMARY KEY主键定义的作用是表示数据唯一,CLUSTER表示基于这个主键列的聚集索引
CREATE TABLE STUDENT1(
STUNO INT CLUSTER PRIMARY KEY,
STUNAME VARCHAR(15) NOT NULL,
TEANO INT,
CLASSID INT
);
-- 默认情况下,达梦的dm.ini中PK_WITH_CLUSTER参数为1,即建表时指定的主键会自动转化为聚集主键
-- 主键语句中不带CLUSTER关键字,这与上面是同义的。
CREATE TABLE STUDENT2(
STUNO INT PRIMARY KEY,
STUNAME VARCHAR(15) NOT NULL,
TEANO INT,
CLASSID INT
);
-- 查看这个索引(基于主键列的索引组织表B+TREE数据结构)
SELECT * from DBA_INDEXES idx WHERE idx.owner='QHDATA_TEST' AND idx.table_name='STUDENT2';
-- 查看索引定义(NAME基于上面查询得来)
SELECT dbms_metadata.get_ddl(OBJECT_TYPE => 'INDEX',NAME=>upper('INDEX33625894'),SCHNAME => 'QHDATA_TEST');
-- 索引定义语句: CLUSTER UNIQUE INDEX , 唯一的聚集索引
CREATE OR REPLACE CLUSTER UNIQUE INDEX "QHDATA_TEST"."INDEX33625893" ON "QHDATA_TEST"."STUDENT1"("STUNO" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;
CREATE OR REPLACE CLUSTER UNIQUE INDEX "SYSDBA"."INDEX33625920" ON "SYSDBA"."STUDENT1"("STUNO" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;
CREATE OR REPLACE CLUSTER UNIQUE INDEX "SYSDBA"."INDEX33625921" ON "SYSDBA"."STUDENT2"("STUNO" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;
------------------------------------------------------------------------------------------------------------------------
-- CLUSTER PRIMARY KEY 主键约束,指明指定列作为基表的聚集索引(也 叫聚簇索引)和主关键字;
-- PRIMARY KEY 主键约束,指明指定列作为基表的主关键字(当PK_WITH_CLUSTER 为0时,即建表时指定的主键不会自动转化为聚集主键;若为 1,则主键自动变为聚集主键。);
-- 这两个等价,都是 CLUSTER UNIQUE INDEX
-- CLUSTER KEY 指定列为聚集索引键,但是这个列是非唯一的字段;
CREATE OR REPLACE CLUSTER INDEX "SYSDBA"."INDEX33625905" ON "QHDATA_TEST"."STUDENT4"("id" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;
-- NOT CLUSTER PRIMARY KEY 主键约束,指明指定列作为基表的非聚集索引主关键字。这个会创建两个索引:
-- 基于这个列的唯一索引 和 基于ROWID的聚集索引
CREATE OR REPLACE UNIQUE INDEX "SYSDBA"."INDEX33625915" ON "SYSDBA"."STUDENT5"("id" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;
CREATE OR REPLACE CLUSTER INDEX "SYSDBA"."INDEX33625914" ON "SYSDBA"."STUDENT5"( STORAGE(ON "MAIN", CLUSTERBTR) ;
-- CLUSTER UNIQUE KEY 指定列为聚集索引键,并且是唯一的;
达梦执行计划¶
SQL 的核心是一种描述性语言,使用者只需定义所需的数据及数据的获取方式由优化器来决定。
可以说,执行引擎相当于汽车的发动机,而查询优化器则是方向盘。若没有合适的优化器指引,再强大的引擎也可能导致我们在高速行驶中撞上内存溢出的障碍
因此,优化器是 SQL 中极为关键的组件。
数据库管理系统的优化器是决定 SQL 执行性能的关键。DM 采用基于代价的优化器,服务器接收到 SQL 语句后,经过语法分析和语义分析,之后进行各种关系代数转换,形成一 系列备选的逻辑执行计划。DM 优化器通过对这些备选逻辑计划进行代价估算和优化,最终 生成一个最优的物理执行计划,交由执行器执行。
优化器工作流程前面说的“生成一个最优的物理执行计划”只是一个相对的概念,计算出一个与实际执 行相接近的代价值是一件困难的事。影响实际执行代价的因素非常多,优化器不可能也没有 必要非常全面地考虑每一个细节,如系统封锁,并发等因素。DM 优化器主要关注的是执行 查询所涉及的表的记录行数,数据页的数量,可利用的索引和统计信息,以及内存,IO 和 CPU 的计算量等。
执行计划分为**预估执行计划**和**实际执行计划**。
如何查看执行计划?
开发人员只关心 SQL 语句能否返回 T1 与 T2 表的关联查询结果,不需要指定该 SQL 如何执行,也就是说不关心该 SQL 是先访问 T1 表还是先访问 T2 表。
对于 SQL 来说,两种访问方式就是两个执行计划,查询优化器 (CBO) 将根据代价也就是开销来选择最优的执行计划。
预估执行计划
-
达梦客户端直接点击菜单栏按钮或按F9生成
-
在 SQL 语句前面加上 EXPLAIN
| 动作 | 使用聚簇索引 | 使用非聚簇索引 |
|---|---|---|
| 列经常被分组排序 | 应 | 应 |
| 返回某范围内的数据 | 应 | 不应 |
| 一个或极少不同值 | 不应 | 不应 |
| 小数目的不同值 | 应 | 不应 |
| 大数目的不同值 | 不应 | 应 |
| 频繁更新的列 | 不应 | 应 |
| 外键列 | 应 | 应 |
| 主键列 | 应 | 应 |
| 频繁修改索引列 | 不应 | 应 |
执行计划操作符,可以参考达梦官方操作手册
操作符:
- NSET2 结果收集 执行计划最顶层操作符
- PRJT2 投影
- SLCT2 选择 表示过滤
- FAGR2 快速聚集 select count(*) from 表; 会自动走这个执行计划
- CSCN2 全表扫描 cluster index scan 的缩写,达梦默认创建的表是索引组织表
- AAGR2 聚集 用于无group by的count,sum,max,min,avg运算
- HAGR2 分组聚集 用于全表扫描GROUP BY聚集
- BLKUP2 回表
- SSEK2 二级索引扫描
- SSCN 索引全扫描不回表
-
CSEK2 聚集索引扫描不回表
-
NSET:结果集收集:NSET 是用于结果集收集的操作符,一般是查询计划的顶层节点,优化工作中无需对该操作符过多关注,一般没有优化空间。
- PRJT:投影:
-
SLCT:选择:
-
表查找操作符
- SSEK2: 是二级索引扫描即先扫描索引,再通过主键、聚集索引、rowid 等信息去扫描表。
- BLKUP :回表:根据二级索引的ROWID 回原表中取出全部数据(b + a)
- CSEK2: 是聚集索引扫描。只需要扫描索引,不需要扫描表,即无需 BLKUP 操作,如果 BLKUP 开销较大时,可考虑创建聚集索引。
- CLUSTER_INDEX_SEEK :聚集索引查找:比如
select cluster_column from table where cluster_column = '123'
- CLUSTER_INDEX_SEEK :聚集索引查找:比如
-
CLUSTER SCAN : 聚集索引全扫描:比如直接查全部的聚集索引列
select cluster_column from table -
**SSCN:**是Second Index scan,即二级索引全扫描,不需要扫描表。比如
second index scan -
**CSCN: **CSCN2是CLUSTER INDEX SCAN的缩写即通过聚集索引扫描全表,全表扫描是最简单的查询,如果没有选择谓词,或者没有索引可以利用,则系统一般只能做全表扫描。
CREATE TABLE "qhdata_warehouse"."dw_addr_admin_area_code" (
"rid" INT NOT NULL,
"update_time" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP() NOT NULL,
"start_time" DATE,
"end_time" DATE,
"version_num" INT NOT NULL,
"lng_lat_GCJ02" VARCHAR(100),
"lng_lat_GCJ02_md5" VARCHAR(64) NOT NULL,
"UA0003" VARCHAR(100),
"UA0004" VARCHAR(100),
"UA0005" VARCHAR(100),
"UA0006" VARCHAR(100),
"UA0007" VARCHAR(100),
"UA0008" VARCHAR(100),
"code_version" VARCHAR(100),
"addr_code" VARCHAR(600),
"check_md5" VARCHAR(64),
"deal_ind" INT,
UNIQUE("lng_lat_GCJ02_md5")
) STORAGE(ON "MAIN", CLUSTERBTR);
-- 聚集索引
CREATE OR REPLACE CLUSTER INDEX "qhdata_warehouse"."INDEX_RID_111" ON "qhdata_warehouse"."dw_addr_admin_area_code"("rid" ASC) STORAGE(ON "MAIN", CLUSTERBTR);
-- 唯一索引
CREATE OR REPLACE UNIQUE INDEX "qhdata_warehouse"."INDEX177922827890000" ON "qhdata_warehouse"."dw_addr_admin_area_code"("rid" ASC) STORAGE(ON "MAIN", CLUSTERBTR);
-- 基于UA0008的索引
CREATE OR REPLACE INDEX "qhdata_warehouse"."INDEX177921343911900" ON "qhdata_warehouse"."dw_addr_admin_area_code"("UA0008" ASC) STORAGE(ON "MAIN", CLUSTERBTR);
-- 基于UA0005的索引
CREATE OR REPLACE INDEX "qhdata_warehouse"."INDEX177921813174100" ON "qhdata_warehouse"."dw_addr_admin_area_code"("UA0005" ASC) STORAGE(ON "MAIN", CLUSTERBTR);
-- 联合索引
CREATE OR REPLACE INDEX "qhdata_warehouse"."mutli_index" ON "qhdata_warehouse"."dw_addr_admin_area_code"("UA0008" ASC,"UA0005" ASC) STORAGE(ON "MAIN", CLUSTERBTR);
-- 主要通过explain和explain for来查看SQL语句的执行计划
explain select * from qhdata_warehouse.dw_addr_admin_area_code where UA0005 = '440300000000' and UA0008 = '440311006001';
explain for select * from qhdata_warehouse.dw_addr_admin_area_code where UA0005 = '440300000000' and UA0008 = '440311006001';
执行计划的每行即为一个计划节点,主要包含三部分信息:
- 缩进越深的越先执行;
- 同样缩进的上面的先执行,下面的后执行;
- 上下的优先级高于内外;
**说明:**越缩进越先执行,即最终缩进分叉了3,4,同样的缩进,从上由下优先级更高,所以这里的3先执行,3下面又有越深的越先执执行,又有1,2 ,所以整个排序执行顺序就出来了,开始看不习惯,大家多看几次就习惯了。
- 第一部分 NEST2、PRJT2、CSCN2 为操作符及数据库具体执行了什么操作。具体详见操作符
- 第二部分的三元组为该计划节点的执行代价,具体含义为[代价,记录行数,字节数]。
- 第三部分为操作符的补充信息。

-
SEEK2:表示这个等值查找使用了**二级索引进行范围查找**,查找范围是
[('440311006001','440300000000'),('440311006001','440300000000')] -
BLKUP2:表示回表,根据二级索引定位 rowid,再根据表的主键、聚集索引、rowid 等信息获取数据行中其它列。
- PRJT2:表示投影,将查询语句中的星号拓展为所有列名。
- NSET:用于结果集收集的操作符,一般是查询计划的顶层节点,优化工作中无需对该操作符过多关注,一般没有优化空间。
执行计划视图
达梦数据库的 v$SQL_PLAN视图主要用于显示缓存中的SQL执行计划信息,在 dm.ini 参数 USE_PLN_POOL !=0 时才统计。
通过查询这个视图,用户可以获取到缓存中的SQL语句的执行计划,这对于监控和分析数据库中的SQL执行情况非常有用。例如,DBA可以通过这个视图来检查哪些SQL语句的执行计划被频繁使用,从而进行性能优化或故障排查。
此外,该视图还可以与DBMS_XPLAN包结合使用,以多种预定义格式显示EXPLAIN PLAN命令的输出,进一步帮助用户理解和优化SQL执行计划。
SELECT NUM_ROWS,LAST_ANALYZED,TEMPORARY FROM USER_TABLES WHERE TABLE_NAME='TEST_TAB1';
统计信息收集¶
当我们发现一些业务表的相关语句存在因为数据的变化而导致语句执行效率差异变大时,我们可以通过设定定时作业对表进行统计信息的收集。
达梦数据库是基于代价的优化器,达梦数据库统计信息不准,会影响到执行计划的估算,导致SQL解析到错误的执行计划,如何判断统计信息有没有收集呢?
为什么要动态更新统计信息呢,数据库经常会在计划缓存中生成了非最优的计划,达梦数据库的优化器是基于代价的优化器,精确的统计信息有助于CBO生成更优的计划,但是统计信息并不会实时更新。所以,统计信息的不准确,就导致CBO生成了非最优的计划。
我们看如下SQL,主要看NUM_ROWS字段,如果没有收集通常是空。第二个LAST_ANALYZED代表收集的时间,如果没有收集这个字段也是空,第三个TEMPORARY字段附带说明,N表示不是临时表,Y表示是临时表,通常如果TEMPORARY=Y 是不用收集的。
SELECT ONWER, TABLE_NAME , NUM_ROWS,LAST_ANALYZED,TEMPORARY FROM ALL_TABLES WHERE TABLE_NAME='bak_20240904180937_ud_cwx';
SELECT ONWER, TABLE_NAME , NUM_ROWS,LAST_ANALYZED,TEMPORARY FROM USER_TABLES WHERE TABLE_NAME='bak_20240904180937_ud_cwx';
当一个表缺失了统计信息我通常用如下语句修复:
-- 1、收集数据库的统计信息,对库上所有模式下的所有用户表以及表上的所有索引生成统计信息
CALL SP_DB_STAT_INIT ();
-- 2、清空库的统计信息
CALL SP_DB_STAT_DEINIT ();
-- 3、对某张表或某个索引生成统计信息 CALL SP_TAB_STAT_INIT ('模式名', '表名或索引名');
对表 SYSOBECTS 生成统计信息 CALL SP_TAB_STAT_INIT ('SYS', 'SYSOBJECTS');
-- 4、清空某张表的统计信息 CALL SP_TAB_STAT_DEINIT ('模式名', '表名');
清空表 SYSOBECTS 的统计信息 CALL SP_TAB_STAT_DEINIT ('SYS', 'SYSOBJECTS');
-- 5、对某个表上所有的列生成统计信息 CALL SP_TAB_COL_STAT_INIT ('模式名', '表名');
对'SYSOBJECTS'表上所有的列生成统计信息 CALL SP_TAB_COL_STAT_INIT ('SYS', 'SYSOBJECTS');
-- 6、清空某个表上所有的列的统计信息 CALL SP_TAB_COL_STAT_DEINIT ('模式名', '表名');
清空'SYSOBJECTS'表上所有的列统计信息 CALL SP_TAB_COL_STAT_DEINIT ('SYS', 'SYSOBJECTS');
-- 7、对指定的列生成统计信息,不支持大字段列和虚拟列
CALL SP_COL_STAT_INIT ('模式名', '表名', '列名');
--对表 SYSOBJECTS 的 ID 列生成统计信息
CALL SP_COL_STAT_INIT ('SYS', 'SYSOBJECTS', 'ID');
-- 8、清空指定列的统计信息
CALL SP_COL_STAT_DEINIT ('模式名', '表名', '列名');
-- 清空表 SYSOBJECTS 的 ID 列统计信息
CALL SP_COL_STAT_INIT ('SYS', 'SYSOBJECTS', 'ID');
-- 9、对表上所有的索引生成统计信息 CALL SP_TAB_INDEX_STAT_INIT ('模式名', '表名');
对 SYSOBJECTS 表上所有的索引生成统计信息 CALL SP_TAB_INDEX_STAT_INIT ('SYS', 'SYSOBJECTS');
-- 10、对指定的索引生成统计信息 CALL SP_INDEX_STAT_INIT ('模式名', '索引名');
-- 对指定的索引 IND 生成统计信息 CALL SP_INDEX_STAT_INIT ('SYSDBA', 'IND');
-- 11、清空指定的索引的统计信息 CALL SP_INDEX_STAT_DEINIT ('模式名', '索引名');
-- 清空指定的索引 IND 的统计信息 CALL SP_INDEX_STAT_DEINIT ('SYSDBA', 'IND');
-- 12、对某个 SQL 查询语句中涉及的所有表和过滤条件中的列(不包括大字段、ROWID)生成统计信息。可能返回的错误提示:
-- 1) 语法分析出错,sql 语句语法错误 2) 对象不支持统计信息,统计的表或者列不存在,或者不允许被统计 CALL SP_SQL_STAT_INIT ('SQL');
-- 对'SELECT * FROM SYSOBJECTS'语句涉及的所有表生成统计信息
CALL SP_SQL_STAT_INIT ('SELECT * FROM SYSOBJECTS');
-- 13、对指定的列生成统计信息,不支持大字段列和虚拟列
CALL SP_COL_STAT_INIT('模式名','表名','列名')
-- 对表 SYSOBJECTS 的 ID 列生成统计信息
CALL SP_COL_STAT_INIT ('SYS', 'SYSOBJECTS', 'ID');
-- 14、清空指定的列的统计信息
CALL SP_COL_STAT_DEINIT('模式名','表名','列名')
-- 清空表 SYSOBJECTS 的 ID 列统计信息
CALL SP_COL_STAT_DEINIT ('SYS', 'SYSOBJECTS', 'ID');
-- 15、对某个表上所有的列,按照指定的采样率生成统计信息
CALL SP_STAT_ON_TABLE_COLS('模式名','表名','采样率')
-- 对'SYSOBJECTS'表上所有的列生成统计信息,采样率 90
CALL SP_STAT_ON_TABLE_COLS('SYS','SYSOBJECTS',90);
-- 16、删除一个表的多维统计信息
CALL SP_TAB_MSTAT_DEINIT('模式名','表名')
优化概述¶
参数配置¶
SQL层面¶
数据库的性能问题最终都要涉及到SQL优化,处理流程基本步骤:生成日志——>日志入库——>分析SQL——>优化方案。对于SQL我们一般优化的原则符合:
- 最优先处理:数量很少(5%),但是执行频率非常高,甚至达到每秒上百次,只要一慢,系统很可能瘫痪。(并发非常高)
- 次优先处理:占大多数(80%),如果有慢的,对系统整体稳定性影响不大,但是会造成局部的某些操作慢(并发一般)
- 最后处理:数量少(15%),往往是很复杂的查询,可能一天就执行几次,对系统整体影响不大,但是优化难度很大。(并发很少特别慢)
慢SQL定位¶
跟踪日志文件是一个纯文本文件,以 dmsql_实例名_日期_时间命名, 默认生成在 DM 安装目录的 log 子目录下。
跟踪日志内容包含系统各会话执行的 SQL 语句、参数信息、错误信息、执行时间等。跟踪日志主要用于分析错误和分析性能问题,基于跟踪日志可以对系统运行状态进行分析。
根据跟踪日志查找慢 SQL
当 INI 参数 ENABLE_MONITOR=1、MONITOR_TIME=1 打开时,显示系统最近 1000 条执行时间超过预定值的 SQL 语句。
默认预定值为 1000 毫秒。预定值可通过 LONG_EXEC_SQLS_CNT 来修改。
可通过 SP_SET_LONG_TIME 系统函数修改,通过 SF_GET_LONG_TIME 系统函数查看当前值。
-- 两个参数均为动态参数,可直接调用系统函数进行修改
SP_SET_PARA_VALUE(1,'ENABLE_MONITOR',1);
SP_SET_PARA_VALUE(1,'MONITOR_TIME',1);
SP_SET_PARA_VALUE(1,'MONITOR_SQL_EXEC',1);
-- LONG_EXEC_SQLS_CNT
-- v$SYSTEM_LONG_EXEC_SQLS 显示服务器启动以来执行时间最长的 20 条 SQL 语句
-- v$LONG_EXEC_SQLS 显示最近 1000 条执行时间较长的 SQL 语句
-- v$SQL_HISTORY 显示执行 sql 的历史记录信息;可以方便用户经常使用的记录进行保存。
ET查询¶
ET 是达梦数据库内置的SQL性能优化分析工具,它可以统计指定会话ID执行的SQL的所有操作符的执行时间。
对于分析优化SQL提供比较直观的数据依据,对于达梦数据库SQL优化,ET的使用是必须要掌握的技能之一。
达梦数据库ET功能默认是关闭,需要设置ini参数,enable_monitor=1、monitor_time=1和monitor_sql_exec=1
-- 查看ET相关参数及其值
select para_name,para_value,para_type from v$dm_ini where para_name in ('ENABLE_MONITOR','MONITOR_TIME','MONITOR_SQL_EXEC')
-- 配置相关参数开启ET功能
SP_SET_PARA_VALUE(1,'ENABLE_MONITOR',1); -- 开启监视
SP_SET_PARA_VALUE(1,'MONITOR_SQL_EXEC',1); -- 监视SQL执行
SP_SET_PARA_VALUE(1,'MONITOR_TIME',1); -- 监视时间
--使用ET分析sql执行效率,语句的执行号为3105,可以通过ET(3105)的方式调用ET
SELECT D.* FROM DMTEST.EMPLOYEES E, DMTEST.DEPT_EMP D WHERE D.EMP_NO = E.EMP_NO LIMIT 10;
ET(3105);
https://www.modb.pro/db/583100
启用SQL日志来辅助分析性能问题¶
在达梦数据库中,DBA可以通过查看系统SQL日志来辅助分析SQL性能问题。
将DM数据库配置文件中的参数SVR_LOG设置为打开,系统会在安装的log目录下生成名为 dmsql_实例名_日期_时间.log 的SQL日志文件。
在该文件中记录了启用SVR_LOG之后数据库接收到的所有SQL语句等信息,DBA可以通过分析该文件来帮助解决问题。
# 开启SQL日志
SP_SET_PARA_VALUE(1, 'SVR_LOG', 1);
重点关注信息:记录执行时间超过200ms的语句;生产环境必须设置为异步日志;设置SQL过滤规则,只记录必要的SQL等。
达梦内存概述¶

达梦的内存结构主要包括**内存池**、缓冲区、排序区、哈希区。 根据系统中子模块的不同功能,对内存进行了上述划分,并采用了不同的管理模式。
这些参数的默认值都很小。 生产环境需要根据服务器的配置进行相应的修改。
达梦数据库服务启动时,会向操作系统申请 6 块独立的内存(数据缓冲区,字典缓冲区,日志缓冲区,共享内存池,备用内存池,sql 缓冲区)常驻。
如果有会话连接,则会去建立相关的内存池(会话内存池,排序内存池,虚拟机内存池等)会话结束后,相关内存池回收。
前者称之为共享内存池(意为全局,整个实例共享),后者称之为运行时内存(意为每个连接独享)。
共享内存池¶
达梦在实例运行期间,需要经常申请或释放小片内存,而向操作系统申请或释放内存时需要进行系统调用,此时可能会引起线程切换,降低系统运行效率。
实例启动时会从操作系统中申请一大片内存,即共享内存池。当实例在运行中需要内存时,可以在共享内存池内申请或者释放内存。
数据缓冲区¶
数据缓冲区保存的是数据页,包括用户更改的数据页和查询时从磁盘读取的数据页。这是DM Server至关重要的内存区域之一。
该区域大小对实例性能的影响较大,设定过小会导致缓冲页命中率低,磁盘I/O频繁;设定过大会导致资源的浪费,导致操作系统内存本身不够用。
实例在启动时,根据配置文件中参数指定的数据缓冲区大小,向操作系统申请一片连续的内存,并将其按数据页大小进行格式化,最后置入自由链中。
数据缓冲区存在三条链来管理被缓冲的数据页:
(1)自由链,用于存放目前尚未使用的内存数据页。
(2)LRU链,用户存放已被使用的内存数据页(包括未修改和已修改的内存数据页)
(3)脏链,用于存放已被修改过的内存数据页。
DM 的buffer区相当于Oracle的buffer cache,数据库缓冲区是DMDB用于缓存数据块的内存区域。
当数据从磁盘读取到内存时,它们通常会被存储在 数据库缓冲区 中,以提高数据访问的性能。缓冲区的大小可以通过配置参数进行调整。
-- 查询buffer相关视图
SELECT distinct name,count(*) FROM v$bufferpool GROUP BY name ORDER BY 2 DESC;
-- 查询BUFFER相关参数
SELECT * FROM V$DM_INI WHERE PARA_NAME LIKE '%BUFFER%';
-- 查询BUFFER相关
SELECT name ,type,value,sys_value,file_value,description FROM v$parameter WHERE upper(name) LIKE upper('%BUFFER%');
达梦数据库中提供了动态性能视图 v$BUFFERPOOL 来监控数据缓冲区的使用情况。该视图结构如下:
| 列 | 数据类型 | 说明 |
|---|---|---|
| ID | 缓冲区ID | |
| NAME | 缓冲区名称 NORMAL/KEEP/RECYCLE/FAST | |
| PAGE_SIZE | 基缓冲区页大小,不包括扩展池页 | |
| N_PAGES | 页数 | |
| N_FIXED | 数据页被引用的次数 | |
| FREE | 空闲页数目 |
同样buffer又分为几个子池,如 normal, keep, recycle, fast, roll用于数据内存中周期管理。
在DM数据库中,buffer 缓冲分为4种,分别为:
- normal缓冲区,对应的
ini参数:在一般的系统中,我们重点需要修改的是2个 buffer 参数, 该参数对性能影响较大:
BUFFER:系统缓冲区大小,以 M 为单位,默认值是1000。推荐值:系统缓冲区大小为可用物理内存的 60%~80%。有效值范围(8~1048576)BUFFER_POOLS:BUFFER系统分区数,每个BUFFER分区的大小为BUFFER/BUFFER_POOLS。默认值是19,在内存不大的情况下,建议调小该值。
- keep缓冲区,常驻的数据都放在keep数据页中,对应的ini参数就是KEEP
KEEP的特性是对缓冲区中的数据页很少或几乎不怎么淘汰出去,主要针对用户的应用是否需要经常处在内存当中。
如果是这种情况,可以指定缓冲区为KEEP。用户可以在创建表空间或修改表空间时,指定表空间属于NORMAL或KEEP缓冲区。
KEEP:KEEP缓冲区大小,以 M 为单位。默认8M,有效值范围(8~1048576)
- recycle缓冲区,高并发系统、使用with as语句较多,临时数据较多需要将这个recycle数据页所占用的内存值调大,对应的ini参数是recycle。
RECYCLE缓冲区供临时表空间使用,记住所有的页大小在初始化实例时已经设定好了,现在使用ini参数修改的是缓冲区内存大小。
- fast缓冲区,fast包含数据页和回滚页,常驻缓冲区,这两者都是由系统自动管理,无需干涉对应的ini参数是fast_pool_pages和fast_roll_pages,代表fast缓冲区的大小为多少数据页。
从参数来看,DM也有类似Oracle的内存自动管理机制,如memory_target.
参数属性分为三种:静态、动态和手动。
-
静态,可以被动态修改,修改后重启服务器才 能生效。
-
动态,可以被动态修改,修改后即时生效。动态参数又分为**会话级**和**系统级**两种。
会话级参数被修改后,新参数值只会影响新创建的会话,之前创建的会话不受影响;系统级参数 的修改则会影响所有的会话。
- 手动,不能被动态修改,必须手动修改 dm.ini 参数文件,然后重启才能生效。
日志缓冲区¶
日志缓冲区是用于存放重做日志的内存缓冲区。为了避免由于直接的磁盘 IO 而使系统性能受到影响,系统在运行过程中产生的日志并不会立即被写入磁盘,而是和数据页一样,先将其放置到日志缓冲区中。那么为何不在数据缓冲区中缓存重做日志而要单独设立日志缓冲区呢?主要是基于以下原因:
- 重做日志的格式同数据页完全不一样,无法进行统一管理;
- 重做日志具备连续写的特点;
- 在逻辑上,写重做日志比数据页 IO 优先级更高。
DM Server 提供了参数 RLOG_BUF_SIZE 对日志缓冲区大小进行控制,日志缓冲区所占用的内存是从共享内存池中申请的,单位为页数量。
SQL缓冲区¶
sql buffer区相当于oracle的shared pool中的一部分或是library cache中的shared sql area。
用于记录sql text, sql execution plan ,plsql obj。
共享池的目的是减少重复SQL语句的解析和优化成本,提高数据库的性能。还有包含类似oracle 的result cache
select name ,type,value,sys_value,file_value,description from v$parameter where upper(name) like upper('%BUFFER%');
CACHE_POOL_SIZE默认值20M
一般在内存小于16G的情况下,建议设置为200M,内存大于16G,小于64G,建议设置为1024M,当内存大于64G时,建议设置为2048M。
运行时内存池¶
除了共享内存池,实例的一些功能模块在运行时还会使用自己的运行时内存池。
这些运行时内存池从操作系统申请一片内存作为本功能模块的内存池来使用,如会话内存池、虚拟机内存池等。
| 共享内存池 | DM Server 在启动时从操作系统申请的一大片内存 | |
| 运行时内存池 | ||
| 数据缓冲区 |
会话内存池¶
在DM库中每个活动会话有自己的运行时内存池vm_pool和会话内存 sess_pool,当 VM_POOL 和SESS_POOL 大小不足时,会向主内存池MEM_POOL申请内存,到私有池上的 VM_POOL 和 SESS_POOL 进行扩展。
每个连接会分配一个session区,应用是用于存储会话级别的数据和变量,在SQL运行期间会分配该内存区1个或多个vm pool
select name ,type,value,sys_value,file_value,description from v$parameter where upper(name) like upper('%session%');
select name ,type,value,sys_value,file_value,description from v$parameter where upper(name) like upper('%vm%');
--MAX_SESSIONS:缺省值10000,静态属性,系统运行同时连接的最大数,取值范围1-15000。在安全版环境下,该参数受LICENSE的限制,取二者中较小者。当会话数达到 MAX_SESSIONS 值后,为了保证管理员可继续管理数据库,允许 SYSDBA 额外开启 10 个会话连接。
--LISTEN_IP:手动属性,与 PORT_NUM 配合使用,监听 IP 地址。若指定,则连接时必须指定与该值一样的 IP,否则创建连接失败。
--MAX_SESSION_STATEMENT:缺省值10000,动态系统级属性,单个会话上允许同时打开的语句句柄最大数,取值范围 64~20480)。
--MAX_SESSION_MEMORY:缺省值0,动态系统级属性,单个会话的运行内存上限,单位 MB,取值范围 0~262144,0 表示不限制。
综合内存查询¶
SELECT name,TOTAL_SIZE,TARGET_SIZE,IS_OVERFLOW,FILE_NAME FROM v$mem_pool;
SELECT name,VALUE,DESCRIPTION FROM v$parameter WHERE name='MEMORY_POOL';
SELECT PARA_NAME,PARA_VALUE,DESCRIPTION ,PARA_TYPE FROM v$dm_ini WHERE PARA_NAME like '%MEMORY_%';
-- 内存总量查询:达梦数据库使用的内存大致等于 BUFFER + MPOOL,对应的 SQL 语句为
select
(select sum(n_pages * page_size)/1024/1024 from v$bufferpool)||'MB' as BUFFER_SIZE, ( select sum(total_size)/1024/1024 from v$mem_pool)||'MB' as mem_pool, (select sum(n_pages * page_size)/1024/1024 from v$bufferpool)+(select sum(total_size)/1024/1024 from
v$mem_pool)||'MB' as TOTAL_SIZE
From dual;
select name, --内存池名称
is_shared, --是否是共享的
is_overflow, --是否用到了备份池
org_size/1024.0/1024.0, --内存池初始大小
TOTAL_size/1024.0/1024.0, --内存池总大小(包括扩展的)
RESERVED_SIZE/1024.0/1024.0, --当前已分配大小(包括扩展的)
DATA_SIZE/1024.0/1024.0, --实际有效字节
EXTEND_SIZE, --每次扩展多少
TARGET_SIZE, --目标大小
N_EXTEND_NORMAL , --TARGET 范围内累计扩展次数
N_EXTEND_EXCLUSIVE --超过 TARGET 累计扩展次数
from v$mem_pool order by TOTAL_size desc;
注意:
1、N_EXTEND_EXCLUSIVE 如果长期大于 0,说明长期从池外扩展,可能存在内存泄露。需要重点关注。
2、用到备份池的话,需要保持高度关注,此时系统非常危险。
3、内存池创建的线程号 creator 可以与 session 的 thrd_id 关联,查看对应的某个会话的内存使用情况。
4、如果 RESERVED_SIZE 比 org_size 小,说明内存池非常空闲,需要把对于的初始内存放小,否则浪费。
5、如果 TOTAL_size 比 TARGET_SIZE 大,说明内存池不够,经常向池外申请,需要把对于的参数调大。尽量保持每个池自持。
2.2 如何判断 BUFFER 空闲还是紧张
select name, --缓冲区名称
n_pages, --页数
free, --空闲页数目
N_DISCARD64 --淘汰的页数
from v$bufferpool
注意重点:
1、如果 free 很多说明该缓冲区很空闲,可以适当的调整降低 buffer 缓冲区参数值。
2、如果 free 项为 0,或者 N_DISCARD64 非零,表示该缓冲区经常淘汰。这种情况,就说明对应的缓冲区
参数太小,导致频繁淘汰,需要调整对应的缓冲区的参数。
SELECT para_name,para_value,MAX_VALUE,DEFAULT_VALUE,DESCRIPTION,PARA_TYPE
FROM v$dm_ini
WHERE para_name LIKE '%MEMORY%';
select a.mem_all mem_size, b.mem_all buffer_size,a.MEM_ALL+b.MEM_ALL MEM_M,a.MEM_USED+b.MEM_USED USED_M
from
(select sum(TOTAL_SIZE)/1024/1024 MEM_ALL,
sum(RESERVED_SIZE)/1024/1024 MEM_USED
from v$mem_pool)a,
(select sum(PAGE_SIZE*N_PAGES)/1024/1024 MEM_ALL,
sum(PAGE_SIZE*(N_PAGES-FREE))/1024/1024 MEM_USED
from v$bufferpool) b
SELECT name, is_shared,CHK_LEAK,IS_OVERFLOW,sum(ORG_SIZE) t_ORG_SIZE,sum(TOTAL_SIZE) t_TOTAL_SIZE,sum(TARGET_SIZE) t_TARGET_SIZE,count(*) cnt FROM V$MEM_POOl
GROUP BY name, is_shared,CHK_LEAK,IS_OVERFLOW order by 6 desc;
达梦内存利用过高分析¶
当内存率使用较高时
- 查看dmserver进程占用内存 ps
- 查看线程内存 top -H -p
- 统计buffer pool和mem_pool内存区使用
- 查找使用大内存进程
- 输出proc meminfo信息
- pmap查看进程内存
https://www.anbob.com/archives/7427.html
数据库内存相关参数¶
| 参数名 | 缺省值 | 属性 | 说明 |
|---|---|---|---|
| MAX_OS_MEMORY | 100 | 静态 | DM服务器能使用的最大内存占操作系统物理内存与虚拟内存总和的百分比,有效值范围(40~100)。当取值100时,服务器不进行内存的检查 注:对于32位版本的DM服务器,虚拟内存最大为2G |
| MEMORY_POOL | 200 | 静态 | 共享内存池大小,以M为单位。共享内存池是由DM管理的内存。有效值范围:32位平台为(642000),64位平台为(6467108864) |
| MEMORY_N_POOLS | 1 | 静态 | 共享内存池个数,有效值范围(0~2048),0与1等价,即共享池不分片。分片时,每池的初始容量为MEMORY_POOL / MEMORY_N_POOLS, 但受最小初始容量为30M限制,因此实际分片数可能会小于MEMORY_N_POOLS,每个池的TARGET也按此方式由MEMORY_TARGET导出 |
| MEMORY_TARGET | 0 | 动态,系统级 | 共享内存池在扩充到此大小以上后,空闲时收缩回此指定大小,以M为单位,有效值范围:32位平台为(02000),64位平台为(067108864),0表示不限制 |
| MEMORY_EXTENT_SIZE | 1 | 静态 | 共享内存池每次扩充的大小,以M为单位,有效值范围(1~10240) |
| MEMORY_LEAK_CHECK | 0 | 动态,系统级 | 是否开启内存泄漏检测。0:否;1:是,此时系统对每一次内存分配都登记到动态视图V$MEM_REGINFO中, 并在释放时解除登记 |
| MEMORY_MAGIC_CHECK | 2 | 静态 | 是否开启对所有内存池的校验。0:不开启;1:开启校验,校验码基于分配出的块地址计算,在被分配空间的头部和尾部写入校验码;2:增强校验,在1的基础上,如果是内存池分配的,则对尾部未使用空间也计算校验码,写入未使用空间的头部 |
| HUGEPAGE_THRESHOLD | 32 | 动态,系统级 | 如果从OS申请内存的尺寸大于等于 HUGEPAGE_THRESHOLD * 2M, 则尝试先申请巨页内存,若失败再申请常规内存; 0表示不尝试使用巨页内存。有效值范围(0~1024)。注:本参数仅对LINUX操作系统有效,使用巨页内存需要对OS进行相关配置 |
| MEMORY_BAK_POOL | 4 | 静态 | 系统备份内存池大小,以M为单位。系统备份内存池是由DM管理的内存。有效值范围(2~10000) |
| HUGE_MEMORY_PERCENTAGE | 50 | 静态 | 指示HUGE_BUFFER中可以借用作常规内存分配的空间百分比,有效值为0~100。 |
| HUGE_BUFFER | 80 | 静态 | HUGE表使用的缓冲区大小,以M为单位。有效值范围(80~1048576) |
| HUGE_BUFFER_POOLS | 4 | 静态 | HUGE BUFFER系统分区数,每个HUGE BUFFER分区的大小为HUGE_BUFFER/HUGE_BUFFER_POOLS。有效值范围(1~512) |
| BUFFER | 100 | 静态 | 系统缓冲区大小,以M为单位。推荐值:系统缓冲区大小为可用物理内存的60%~80%。有效值范围(8~1048576) |
| BUFFER_POOLS | 19 | 静态 | BUFFER系统分区数,每个BUFFER分区的大小为BUFFER/BUFFER_POOLS。有效值范围(1~512) |
| FAST_POOL_PAGES | 3000 | 静态 | 快速缓冲区页数。有效值范围(0~99999999)。 FAST_POOL_PAGES的值最多不能超过BUFFER总页数的一半,如果超过,系统会自动调整为BUFFER总页数的一半 |
| FAST_ROLL_PAGES | 1000 | 静态 | BUFFER中FAST POOL回滚页数量。有效值范围(09999999),最多不超过FAST_POOL_PAGES的75%,如果超过,系统会自动调整。填充规则:将回滚表空间0号文件的0FAST_ROLL_PAGE-1号页填入FAST POOL中 |
| KEEP | 8 | 静态 | KEEP缓冲区大小,以M为单位。有效值范围(8~1048576) |
| RECYCLE | 64 | 静态 | RECYCLE缓冲区大小,以M为单位。有效值范围(8~1048576) |
| RECYCLE_POOLS | 19 | 静态 | RECYCLE缓冲区分区数,每个RECYCLE分区的大小为RECYCLE/RECYCLE_POOLS。有效值范围(1~512) |
| MULTI_PAGE_GET_NUM | 1 | 动态,系统级 | 缓冲区最多一次读取的页面数。有效值范围(1~64) 注:当数据库加密时不支持多页读取,此时DM.INI中此参数值无效 |
| PRELOAD_SCAN_NUM | 0 | 动态,系统级 | 数据页首次预加载时连续扫描的页数,有效值范围(0~64)。取值为0时关闭数据页预加载功能 注:PRELOAD_SCAN_NUM实际有效范围为(0 ~ EXTENT_SIZE – 2),当大于EXTENT - 2时将会间接失效预加载 |
| PRELOAD_EXTENT_NUM | 0 | 动态,系统级 | 数据页首次预加载的簇数量,有效值范围(0~64)。取值为0时关闭数据页预加载功能 |
| SORT_FLAG | 0 | 动态,会话级 | 排序机制,0:原排序机制;1:新排序机制 |
| SORT_BUF_SIZE | 2 | 动态,会话级 | 原排序机制下,排序缓存区最大值,以M为单位。有效值范围(1~2048) |
| SORT_BUF_GLOBAL_SIZE | 1000 | 动态,系统级 | 新排序机制下,排序全局内存使用上限,以M为单位。有效值范围(10~4294967294) |
| SORT_BLK_SIZE | 1 | 动态,会话级 | 新排序机制下,每个排序分片空间的大小,以M为单位,必须小于SORT_BUF_GLOBAL_SIZE。有效值范围(1~50) |
| HAGR_HASH_SIZE | 100000 | 动态,会话级 | HAGR操作时,建立HASH表的桶个数。有效值范围(10000~100000000) |
| MAL_LEAK_CHECK | 0 | 动态,系统级 | 是否打开MAL内存泄露检查。0:关闭;1:打开 MAL_LEAK_CHECK为1时,可查询V$MAL_USING_LETTERS检查MAL内存泄露。 |
| HJ_BUF_GLOBAL_SIZE | 500 | 动态,系统级 | HASH 连接操作符的数据总缓存大小(>= HJ_BUF_SIZE),系统级参数,以M为单位。有效值范围(10~500000) |
| HJ_BUF_SIZE | 50 | 动态,会话级 | 单个HASH连接操作符的数据总缓存大小,以M为单位,必须小于HJ_BUF_GLOBAL_SIZE。有效值范围(2~100000) |
| HJ_BLK_SIZE | 1 | 动态,会话级 | HASH连接操作符每次分配缓存(BLK)大小,以M为单位,必须小于HJ_BUF_SIZE。有效值范围(1~50) |
| HAGR_BUF_GLOBAL_SIZE | 500 | 动态,系统级 | HAGR、DIST、集合操作、SPL2、NTTS2以及HTAB操作符的数据总缓存大小(>= HAGR_BUF_SIZE),系统级参数,以M为单位。有效值范围(10~1000000) |
| HAGR_BUF_SIZE | 50 | 动态,会话级 | 单个HAGR、DIST、集合操作、SPL2、NTTS2以及HTAB操作符的数据总缓存大小,以M为单位。有效值范围(2~500000)。 如果HAGR_BUF_SIZE设置的值满足范围且大于HAGR_BUF_GLOBAL_SIZE,那么会在HAGR_BUF_GLOBAL_SIZE/2和500000两个值中,选出较小的那个,作为新的HAGR_BUF_SIZE值。 |
| HAGR_BLK_SIZE | 1 | 动态,会话级 | HAGR、DIST、集合操作、SPL2、NTTS2以及HTAB操作符每次分配缓存(BLK)大小,以M为单位,必须小于HAGR_BUF_SIZE。有效值范围(1~50) |
| MTAB_MEM_SIZE | 8 | 静态 | MTAB缓存BDTA占用内存空间的大小,以KB为单位,有效值范围(1~1048576) |
| FTAB_MEM_SIZE | 0 | 静态 | FTAB缓存BDTA占用内存空间的大小,以KB为单位。取值范围为(0~64 * 1024)。0表示使用MTAB,大于0时才使用FTAB。当取值小于32时,FTAB_MEM_SIZE均使用32 |
| MMT_SIZE | 0 | 动态,会话级 | 是否使用MMT。0:不启用;其他有效值:启用,并确定单个映射文件大小,必须小于MMT_GLOBAL_SIZE。有效值范围(0~64),单位MB |
| MMT_GLOBAL_SIZE | 4000 | 动态,系统级 | 系统总共使用MMT的文件总大小,单位MB,有效值范围(10~1000000),仅在MMT_SIZE大于0时有效 |
| MMT_FLAG | 1 | 动态,会话级 | MMT存储数据方式。1:按页存储;2:BDTA存储。仅在MMT_SIZE大于0时有效 |
| DICT_BUF_SIZE | 5 | 静态 | 字典缓冲区大小,以M为单位,有效值范围(1~2048)。单位:MB |
| HFS_CACHE_SIZE | 160 | 动态,系统级 | HUGE表 I/U/D 时HDTA_BUFFER缓存池大小,单位为MB。有效值范围(160~ 2000) |
| VM_STACK_SIZE | 256 | 静态 | 系统执行时虚拟机堆栈大小,单位为K,堆栈的空间是从操作系统中申请的,有效值范围(64~256*1024) |
| VM_POOL_SIZE | 64 | 静态 | 系统执行时虚拟机内存池大小,在执行过程中用到的内存大部分是从这里申请的,它的空间是从操作系统中直接申请的,有效值范围(32~1024*1024) |
| VM_POOL_TARGET | 32768 | 静态 | 虚拟机内存池能扩充到的最大大小,以KB为单位,有效值范围(0~10*1024*1024),0表示不限制 |
| SESS_POOL_SIZE | 64 | 动态,系统级 | 会话缓冲区大小,以KB为单位,有效值范围(16~1024*1024)。若所申请的内存超过实际能申请的大小,则系统将按16KB大小重新申请 |
| SESS_POOL_TARGET | 32768 | 动态,系统级 | 会话缓冲区能扩充到的最大大小,以KB为单位,有效值范围(0~10*1024*1024),0表示不限制 |
| RT_HEAP_TARGET | 8192 | 动态,系统级 | 会话上用于动态对象存储的RT_HEAP最大可扩展到的大小,以K为单位,有效值范围(8192~10*1024*1024) |
| VM_MEM_HEAP | 0 | 动态,系统级 | VM是否使用HEAP分配内存。0:MEMORY POOL模式;1:HEAP模式;2:MEMORY POOL和HEAP混合模式 |
| RFIL_RECV_BUF_SIZE | 16 | 静态 | 控制服务器启动时,进行REDO操作过程中,REDO日志文件恢复时BUFFER的大小,以MB为单位,有效值范围(16~4000) |
| COLDATA_POOL_SIZE | 0 | 动态,系统级 | COLDATA池的大小,以M为单位 |
| HAGR_DISTINCT_HASH_TABLE_SIZE | 10000 | 动态,会话级 | 分组DISTINCT操作中HASH表的大小(桶数)。取值范围为(10000~100000000) |
| CNNTB_HASH_TABLE_SIZE | 100 | 动态,会话级 | 指定CNNTB操作符中创建HASH表的大小。有效值范围(100~100000000) |
| GLOBAL_RTREE_BUF_SIZE | 100 | 动态,会话级 | R树全局缓冲区大小,以MB为单位 |
| SINGLE_RTREE_BUF_SIZE | 10 | 动态,会话级 | 单个R树的缓冲区大小,以MB为单位,必须小于GLOBAL_RTREE_BUF_SIZE |
| SORT_OPT_SIZE | 1 | 静态 | 整型/浮点型数据排序优化辅助空间大小,对应待排序数组的最大最小差值,单位M,有效值范围(0~1024)。取值1M时对应待排序数组的最大最小差值为262144,超过则不能使用优化。 |
| TSORT_OPT | 1 | 动态,系统级 | 排序优化选项。0:排序操作一律使用估算的行数分配内存(至少2M);1:打开优化,排序操作结果行数较少时,使用实际的记录行数分配内存 |