DM -DCP
DM 表管理
堆表
堆表是指采用了物理 ROWID 形式的表,即使用文件号、页号和页内偏移而 得到 ROWID 值,这样就不需存储 ROWID 值,可以节省空间。逻辑 ROWID 在插入或修改 过程中,为了确保 ROWID 的唯一性,需要依次累加而得到值,这样就影响了效率,而堆表 只需根据自己的文件号、页号和页内偏移就可以得到 ROWID,提高了效率
- 达梦默认的表是
索引组织表
,达梦既支持索引组织表又支持堆表。- Oracle默认的表是堆表
堆表的创建
一、INI 参数方式
用户可以在配置文件中,添加 LIST_TABLE 参数:
- 如果 LIST_TABLE = 1,则在未显式指定表是否为堆表或非堆表时,默认情况下创建的表为堆表;
- 如果 LIST_TABLE = 0,则在未显式指定表是否为堆表或非堆表时,默认情况下创建的表为普通表形式。
二、SQL语句显示指定
与堆表创建形式相关的关键字有三个,分别是 NOBRANCH、BRANCH、 CLUSTERBTR。
- NOBRANCH:如果指定为 NOBRANCH,则创建的表为堆表,并发分支个数为 0,非并发分支个数为 1;
- BRANCH(n,m):如果为该形式,则创建的表为堆表,并发分支个数为 n,非并发个数为 m;
- BRANCH n:指定创建的表为堆表,并发分支个数为 n,非并发分支个数为 0;
- CLUSTERBTR:创建的表为非堆表,即普通 B 树表。
分支数目主要用于插入场景中。适当提高分支数量可有效地提升并发数据处理效率,但是分支过多又会增加扫描的效率,因此,合适的<BRANCH 数>和<NOBRANCH 数>值需用户根据实际情况来决定。<BRANCH 数>主要在 FLDR 导入和查询插入等并发、批量插入场景中 使用;<NOBRANCH 数>在非并发、单行插入场景中使用。
如下例创建的 LIST_TABLE 表有并发分支 2 个,非并发分支 4 个。
create table A2(id int, name varchar(20)) storage(initial 1, next 1, branch(2,4));
三、图形化界面创建
优缺点
- 优点:
- 并发插入性能高
- 缺点:
- 查询效率低
- DM暂时不支持堆表的列存储
- 堆表进行alter操作后,数据记录ROWID可能发生改表,会引起索引重建
- 水平分区堆表主表及其各字表必须位于同一表空间
其他操作
- 查看索引类型 --堆表的索引类型:FLAT 索引组织表索引类型:CLUSTER
• select * from dba_indexes where table_name = 'TABLE_1'
• 查看LIST_TABLE参数 select * from v$dm_ini where para_name='LIST_TABLE'
• 修改LIST_TABLE参数
• Sp_set_para_value(1,’LIST_TABLE’,1);
分区表(dcp)
分区是指将表、索引等数据库对象划分为较小的可管理片段的技术,每一个片段称为分区子表或分区索引。一个表被分区后,对表的查询操作可以局限于某个分区进行,而不是整 个表,这样可以大大提高查询速度。
DM 提供了水平分区方式。水平分区包括范围、哈希和列表三种方式,企业可以使用合适的分区方法,如日期(范围)、区域(列表),对大量数据进行分区。由于 DM 划分的分区是相互独立且可以存储于不同的存储介质上的,完全可满足企业高可用性、均衡 IO、降低维护成本、提高查询性能的要求。
由于每一个分区都以一个子表作为实体,那么不同分区可以存储于相同表空间,也可以位于不同的表空间中。将这些分区放在不同的表空间中具有以下的好处:
- 减少所有数据都损坏的可能性,一个表空间损坏不影响其他表空间,提高可用性;
- 恢复时间大大减少;
- 可以将同一个表中的数据分布在不同的磁盘上,从而均衡磁盘上的 I/O 操作;
- 提高了表的可管理性、可利用性和访问效率。
分区操作对现存的应用和运行在分区表上的标准 DML 语句来说是透明的。但是,可以通过在 DML 中使用分区子表名字来对应用进行编程,使其充分利用分区的优点。
范围分区
范围(range)水平分区:对表中的某些列(分区列是数字或是日期类型)上值的范围进行分区,根据某个值的范围,决定将该数据存储在哪个分区上;
create
table "JEECG"."TABLE_2"
(
"id" int,
"name" VARCHAR2(50)
)
PARTITION BY RANGE
(
"id"
)
(
PARTITION "PART_1" VALUES LESS THAN (10),
PARTITION "PART_2" VALUES LESS THAN (20),
PARTITION "PART_3" VALUES LESS THAN (maxvalue)
)
storage
(
initial 1 ,
next 1 ,
minextents 1,
fillfactor 0
) ;
列表分区
--列表分区的分区列适合字符串类型,list分区的分区键必须唯一,默认为DEFAULT
CREATE TABLE sales(
sales_id INT,
saleman CHAR(20),
saledate DATETIME,
city CHAR(10)
)
PARTITION BY LIST(city)(
PARTITION p1 VALUES ('北京', '天津'),
PARTITION p2 VALUES ('上海', '南京', '杭州'),
PARTITION p3 VALUES ('武汉', '长沙'),
PARTITION p4 VALUES ('广州', '深圳')
);
哈希分区
在很多情况下,用户无法预测某个列上的数据变化范围,因而无法实现创建固定数量的 范围分区或 LIST 分区。
在这种情况下,DM 哈希分区提供了一种在指定数量的分区中均等地划分数据的方法, 基于分区键的散列值将行映射到分区中。当用户向表中写入数据时,数据库服务器将根据一 个哈希函数对数据进行计算,把数据均匀地分布在各个分区中。在哈希分区中,用户无法预 测数据将被写入哪个分区中。
建议分区的数量采用 2 的 n 次方,这样可以使得各个分区间数据分布更加均匀
CREATE TABLE sales01(
sales_id INT,
saleman CHAR(20),
saledate DATETIME,
city CHAR(10)
)
PARTITION BY HASH(city)(
PARTITION p1,
PARTITION p2,
PARTITION p3,
PARTITION p4
);
组合分区、多级分区
在很多情况下,经过一次分区并不能精确地对数据进分类,这时需要多级分区表。
例如,创建一个产品销售记录表 sales,记录产品的销量情况。由于产品需要按地点和销售时间进行统计,则可以对该表进行 LIST-RANGE 分区。
DM 支持最多八层多级分区
CREATE TABLE SALES(
SALES_ID INT,
SALEMAN CHAR(20),
SALEDATE DATETIME,
CITY CHAR(10)
)
PARTITION BY LIST(CITY)
SUBPARTITION BY RANGE(SALEDATE) SUBPARTITION TEMPLATE(
SUBPARTITION P11 VALUES LESS THAN ('2012-04-01'),
SUBPARTITION P12 VALUES LESS THAN ('2012-07-01'),
SUBPARTITION P13 VALUES LESS THAN ('2012-10-01'),
SUBPARTITION P14 VALUES EQU OR LESS THAN (MAXVALUE)) (
PARTITION P1 VALUES ('北京', '天津')
(
SUBPARTITION P11_1 VALUES LESS THAN ('2012-10-01'),
SUBPARTITION P11_2 VALUES EQU OR LESS THAN (MAXVALUE)
),
PARTITION P2 VALUES ('上海', '南京', '杭州'),
PARTITION P3 VALUES (DEFAULT)
);
间隔分区
在创建范围分区表时,可通过“INTERVAL <间隔表达式>”子句将该范围分区表指定 为间隔分区表。当对间隔分区表中的数据进行插入或更新操作时,若新的数据无法匹配现有 的分区子表,则系统将自动以用户指定的现有分区的末尾临界值为起始值,以<间隔表达式> 指定的值为间隔值创建一个可以匹配新数据的间隔分区。
可以通过
select * from SYSHPARTTABLEINFO
查看分区信息
- NUMTOYMINTERVAL(N,INTERVAL_UNIT);
函数说明:通过制定的间隔时间来进行时间的跨越
例如:
select sysdate+ NUMTOYMINTERVAL(2,'YEAR'); 2年后
select sysdate+ NUMTOYMINTERVAL(2,'MONHT'); 2月后
• NUMTODSINTERVAL(N,INTERVAL_UNIT);
例如:
select sysdate+ NUMTODSINTERVAL(2,'DAY'); 2天后
select sysdate+ NUMTODSINTERVAL(2,'MONHT'); 2月后
CREATE TABLE "JEECG"."TABLE_3"
(
"id" INT,
"create_date" DATETIME(6))
PARTITION BY RANGE("create_date")
INTERVAL(NUMTOYMINTERVAL(2, 'MONTH'))
(
PARTITION "PART_1" VALUES LESS THAN(DATETIME'2012-04-01 00:00:00') STORAGE(ON "JEECG", CLUSTERBTR) ,
PARTITION "PART_2" VALUES LESS THAN(DATETIME'2012-07-01 00:00:00') STORAGE(ON "JEECG", CLUSTERBTR)
) STORAGE(ON "JEECG", CLUSTERBTR) ;
分区表维护
- 数据字典 Select * from dba_tab_partitions where table_owner=’TEST’;
- 增加分区 ALTER TABLE TEST.T1 add partition pn values less than(maxvalue);
- 删除分区 --只能对范围分区和 LIST 分区进行删除分区,哈希分区不支持删除分区。 Alter table test.t1 drop partition pn;
- 合并分区 --仅范围分区表和 LIST 分区表支持合并分区。其中,合并的RANGE分区必须是范围相邻的两分区。 --合并分区会导致数据的重组和分区索引的重建,因此,合并分区可能会比较耗时,所需时间取决于分区数据量的大小。 alter table test.t1 merge partitions p2,p3 into partition p2_3;
- 拆分分区 --仅范围分区表和 LIST 分区表支持拆分分区 --拆分分区会导致数据的重组和分区索引的重建,因此,拆分分区可能会比较耗时,所需时间取决于分区数据量的大小 alter table test.t1 split partition P2_3 at(200) into (partition p2, partition p3);
- 交换分区 --仅范围分区和 LIST 分区支持交换分区,哈希分区表不支持。 --注意:交换时,会普通表的所有数据全部交换过来,包括不属于这个 分区的数据也一起交换过来,所以我们在交换分区的时候,要把普通表数据整理好 ALTER TABLE TEST.T1 EXCHANGE PARTITION P2
将非分区表转换为分区表
- 将分区表的数据导出来
- 建立一个和分区表结构一样的分区表
- 将数据导入到分区表
总结
外部表(dcp)
外部表,是指不存在于数据库中的表。通过向达梦提供描述外部表的元数据,可以把一个操作系统文件当成一个只读的数据库表,就像这些数据存储在一个普通数据库表中一样来进行访问
外部表的数据存储在操作系统中,是操作系统文件,建立外部表的时候,不会产生段,页簇等存储结构,只有与表相关的定义放在数据字典中。在数据库中不能对外部表的内容进行修改,不能对外部表建立主键,索引,外键。不需要将外部表的数据载入到数据库中来,通过sql 解码器来访问外部表
建立外部表
- 加载数据文件
CREATE EXTERNAL TABLE "JEECG"."TABLE_4"
(
"id" VARCHAR(50),
"name" VARCHAR(50))
FROM DATAFILE 'D:\texta.txt' PARMS(FIELDS DELIMITED BY ',', ERRORS 0);
- 通过配置文件创建
a.ctl文件:
LOAD DATA
INFILE 'D:\texta.txt'
INTO TABLE TABLE_5.EXT
FIELDS ','
create external table "JEECG"."TABLE_5"
(
"id" VARCHAR(50),
"name" VARCHAR(50)
) from 'D:\a.ctl';
使用说明
- <表名>指定了所要建立的外部基表名。如果<模式名>缺省,则缺省为当前模式。 表名需要是合法的标识符,且满足 SQL 语法要求;
- 外部表的表名最大长度为 128 个字符;
- 所建外部基表至少要包含一个<列名>指定的列,在一个外部基表中,各<列名>不 得相 同。一张外部基表中至多可以包含2048 列;
- 外部基表不能存在大字段列;
- 外部基表不能存在任何约束条件;
- 外部基表不能为临时表,不能建立分区;
- 外部基表上不能建立任何索引;
- 外部基表是只读的,不存在表锁,不允许任何针对外部表的增删改数据操作,不允许TRUNCATE 外部表操作;
- 控制文件路径,以及数据文件路径建议采用绝对路径;
临时表
当处理复杂的查询或事务时,由于在数据写入永久表之前需要暂时存储一些行信息或需要保存查询的中间结果,可能需要一些表来临时存储这些数据。DM 允许创建临时表来保存会话甚至事务中的数据。在会话或事务结束时,这些表上的数据将会被自动清除。
临时表中的数据不能像在其它永久表中的数据那样进行备份,当事务结束或会话断开时,数据就会被清空。在临时表创建过程中,不会像永久表和索引那样自动分配数据段,而是仅当第一次执行 DML 语句时,才会为临时表在临时表空间中分配空间。并且,对于不同的会话,临时表上的数据是独享的,不会互相干扰,即会话 A 不能访问会话 B 临时表上的数据。
对复杂查询的传统响应方式之一是使用一个视图,使复杂查询更易于操作。但是,视图在每次访问时都需要执行,因而大大降低了性能。而通过 AS SELECT 子句建立的临时表是将复杂查询的结果通过临时 B 树记录了下来,下次访问不用重新执行查询就可以获得数据,并且会话或事务结束后数据将自动删除,是复杂查询的一个优秀的解决方案,且提高了性能。
DM 临时表支持以下功能:
- 在临时表中,会话可以像普通永久表一样更新、插入和删除数据;
- 临时表的 DML 操作产生较少的 REDO 日志;
- 临时表支持建索引,以提高查询性能;
- 在一个会话或事务结束后,数据将自动从临时表中删除;
- 不同用户可以访问相同的临时表,每个用户只能看到自己的数据;
- 临时表的数据量很少,意味着更高效的查询效率;
- 临时表的表结构在数据删除后仍然存在,便于以后的使用;
- 临时表的权限管理跟普通表一致。
-- 临时表 ON COMMIT 关键词指定表中的数据是事务级还是会话级的,默认情况下是事务级的。 -- 1. ON COMMIT DELETE ROWS:指定临时表是事务级的,每次事务提交或回滚之后,表中所有数据都被删除; -- 2. ON COMMIT PRESERVE ROWS:指定临时表是会话级的,会话结束时才清空表,并释放临时 B 树。 CREATE GLOBAL TEMPORARY TABLE TMP_EMP( EMPNO INT PRIMARY KEY, ENAME VARCHAR(15) NOT NULL, JOB VARCHAR(10)) ON COMMIT DELETE ROWS;
清空表
DM8 支持3种的方式来删除表中的所有行
- delete
- drop
- truncate
区别:
- 空间释放:drop>truncate>delete
- 应用范围:
- truncate 只能对 table
- delete 可以是 table ,view. truncate 和 delete 只删除数据
- drop 则删除整个表包括表结构和数据。
- delete 是 DML 语句,truncate 和 drop 是 ddl 语句
- Delete 是可以带 where 进行过滤的
- Delete 记录undo日志,所以效率慢;truncate 不会记录undo日志,所以效率快。
- Delete 删除会记录redo日志。
序列、同义词、物化试图
序列
序列(sequence)是 DM 数据库中的数据库实体之一。通过使用序列,多个用户可以产生和使用一组不重复的有序整数值。比如可以用序列来自动地生成主关键字值。序列通过提供唯一数值的顺序表来简化程序设计工作
一旦序列生成,用户就可以在 SQL 语句中用以下伪列来存取序列的值:
- CURRVAL 返回当前的序列值;
- NEXTVAL 如果为升序序列,序列值增加并返回增加后的值;如果为降序序列,序列值减少并返回减少后的值。
CREATE SEQUENCE "JEECG"."S3" INCREMENT BY 1 START WITH 1 MAXVALUE 9223372036854775807 MINVALUE 1 NOCYCLE NOCACHE NOORDER ; select JEECG.s3.NEXTVAL SELECT JEECG.s3.CURRVAL
同义词
同义词相当于模式对象的别名,起着连接数据库模式对象和应用程序的作用。假如模式对象需要更换或者修改,则不用修改应用程序而直接修改同义词就可以了。
同义词是用来实现下列用途的数据库对象:
- 为可以存在于本地或远程服务器上的其他数据库对象(称为基础对象)提供备用名称;
- 提供抽象层以免客户端应用程序对基础对象的名称或位置进行更改。
同义词的好处在于用户可能需要某些对象在不同的场合采用不用的名字,使其适合不同人群的应用环境。例如,创建表 product,如果客户不认识这个英文词,这时可以增加同义词,命名"产品",这样客户就有较直观的观念,一目了然。s
- 普通同义词
CREATE SYNONYM "JEECG"."yb_test_hasten_work_a" FOR "JEECG"."SPLIT_ROW_TYPE";
- 公共同义词
物化试图
- 刷新时机
- ON DEMAND((手动刷新)
由用户通过 REFRESH 语法进行手动刷新。如果指定了 START WITH 和 NEXT子句就没有必要指定 ON DEMAND。
- ON COMMIT
在相关表上视图提交时进行快速刷新。刷新是由异步线程执行的,因此COMMIT 执行结束后可能需要等待一段时间物化视图数据才是最新的。
- NEVER REFRESH
物化视图从不进行刷新。可以通过 ALTER MATERALIZED VIEW <物化视图名> FRESH 进行更改。
- START WITH … NEXT
START WITH 用于指定首次刷新物化视图的时间,NEXT 指定自动刷新的间隔;
如果省略 START WITH 则首次刷新时间为当前时间加上 NEXT 指定的间隔;
如果指定 START WITH 省略 NEXT 则物化视图只会刷新一次;
如果二者都未指定物化视图不会自动刷新。
- 刷新选项
- WITH PRIMARY KEY(默认选项)
要求
- 只能基于单表
- 必须含有 PRIMARY KEY 约束,选择列必须直接含有所有的 PRIMARY KEY(UPPER(col_name)的形式不可接受)
- 不能含有对象类型
- WITH ROWID
要求:
- 只能基于单表
- 不能含有对象类型
- 如果使用 WITH ROWID 的同时使用快速刷新,则必须将 ROWID 提取出来,和其他列名一起,以别名的形式显示
- 刷新模式
- FAST
根据相关表上的数据更改记录进行增量刷新。普通 DML 操作生成的记录存在于物化视图日志。使用 FAST 刷新之前,必须先建好物化视图日志。
- COMPLETE
通过执行物化视图的定义脚本进行完全刷新。
- FORCE
默认选项。当快速刷新可用时采用快速刷新,否则采用完全刷新。
- QUERY 选项
- ENABLE
允许物化视图用于查询改写。
- DISABLE
禁止物化视图用于查询改写
- BUILD选项
- BUILD IMMEDIATE
BUILD IMMEDIATE 为立即填充数据,默认为立即填充;
- BUILD DEFERRED
BUILD DEFERRED 为延迟填充,使用这种方式要求第一次刷新必须为 COMPLETE 完全刷新。
索引管理
统计信息
对象统计信息描述数据是如何在数据库中存储的,统计信息是优化器(CBO)的代价计算的依据,可以帮助优化器较精确地估算成本,对执行计划的选择起着至关重要的作用。达梦中的优化器都是基于代价的优化器
达梦数据的统计信息分三种类型:表统计信息、列统计信息、索引统计信息。
统计信息生成过程分以下三个步骤:
- 确定采样的数据:根据数据对象,确定需要分析哪些数据。
- 表:计算表的行数、所占的页数目、平均记录长度
- 列:统计列数据的分布情况
- 索引:统计索引列的数据分布情况
- 确定采样率
根据数据对象的大小,通过内部算法,确定数据的采样率。采样率与数据量成反比。 - 生成直方图
有两种类型的直方图:频率直方图和等高直方图。根据算法分析表的数据分布特征, 确定直方图的类型。频率直方图的每个桶(保存统计信息的对象)的高度不同,等高直方图每个桶的高度相同。例如,对列生成统计信息,当列值分布比较均匀时,会采用等高直方图,否则,采用频率直方图
在执行查询时,如果数据对象存在统计信息,代价算法可以根据统计信息中的数据,比较精确地计算出操作所需花费的成本,以此来确定连接方式、对象访问路径、连接顺序,选择最优的执行计划。
--查询JEECG模式下ACT_HI_ACTINST表的id_字段的统计信息
DBMS_STATS.COLUMN_STATS_SHOW('JEECG','ACT_HI_ACTINST','PROC_DEF_ID_')
--更新已有统计信息
DBMS_STATS.UPDATE_ALL_STATS
--查询jeecg用户的统计信息
DBMS_STATS.GATHER_SCHEMA_STATS('JEECG')
索引
索引是与表相关的可选的结构(聚簇索引除外),它能使对应于表的 SQL 语句执行得更快,因为有索引比没有索引能更快地定位信息。DM8 索引能提供访问表的数据的更快路径,可以不用重写任何查询而使用索引,其结果与不使用索引是一样的,但速度更快。
要在用户自己的模式中创建索引,至少要满足如下条件之一:
- 要被索引的表是在自己的模式中 ;
- 在要被索引的表上有 CREATE INDEX 权限;
- 具有 CREATE ANY INDEX 数据库权限。
要在其他模式中创建索引,用户必须具有 CREATE ANY INDEX 数据库权限
聚簇索引(一级索引)和二级索引的区别
1. 一级索引存储的是数据本身,不需要回表,效率快 2. 二级索引存储的是主键的值,需要回表,效率慢
聚簇索引
DM8 中表(列存储表和堆表除外)都是使用 B+树索引结构管理的,每一个普通表都有且仅有一个聚集索引,数据都通过聚集索引键排序,根据聚集索引键可以快速查询任何记录。 当建表语句未指定聚集索引键时,DM8 的默认聚集索引键是 ROWID。若指定索引键,表中数据都会根据指定索引键排序。
- 建表后,DM8 也可以用创建新聚集索引的方式来重建表数据,并按新的聚集索引排序。
- 新建聚集索引会重建这个表以及其所有索引,包括二级索引、函数索引,是一个代价非常大的操作
- 删除聚集索引时,缺省以 ROWID 排序,自动重建所有索引;
- 若聚集索引是默认的 ROWID 索引,不允许删除;
CREATE CLUSTER INDEX clu_emp_name ON emp(ename);
唯一索引
索引可以是唯一的或非唯一的。唯一索引可以保证表上不会有两行数据在键列上具有相同的值,非唯一索引不会在键列上施加这个限制。
用户可以在希望的列上定义 UNIQUE 完整性约束,DM8 通过自动地在唯一键上定义一个
唯一索引来保证 UNIQUE 完整性约束。
CREATE UNIQUE INDEX dept_unique_index ON dept (dname) STORAGE (ON users);
函数索引
基于函数的索引促进了限定函数或表达式的返回值的查询,该函数或表达式的值被预先计算出来并存储在索引中。
CREATE INDEX IDX ON EXAMPLE_TAB(COLUMN_A + COLUMN_B);
复合索引
索引由表中的多列构成,注意先后顺序
在复合索引中,单独使用前导列(第一列)优化器会走二级索引,单独使用非前导列,优化器不会走二级索引,会走全表扫,如果同时使用复合索引字段,优化器会走二级索引。
索引在查询语句里面是否会用到和 sql 编写相关。包括索引的扫描方 式,都会根据表中的列值分布,统计信息,过滤字段的不同而不同
create index test.emp_ind2 on test.emp(employee_id,employee_name) tablespace IND;
位图索引
对低基数的列创建位图索引,列上的值的类型少的情况下使用位图索引
全文索引
全文检索技术是智能信息管理的关键技术之一,其主要目的就是实现对大容量的非结构化数据的快速查找,DM 实现了全文检索功能,并将其作为 DM 服务器的一个较独立的组件,提供更加准确的全文检 索功能,较好地解决了模糊查询方式带来的问题。
DM 中,全文索引必须在基表定义,而不能在系统表,视图,临时表,列存表,外部表上定义,同一个只能创建一个全文索引,在创建全文索引的时候,用户可以为分词器定义分词参数,即控制分词器的数量。
全文检索的中文分词依赖系统词库,该词库是只读的,不允许修改。
- CHINESE_LEXER --中文最少分词
- CHINESE_VGRAM_LEXER --机械双字分词
- CHINESE_FP_LEXER 中文最多分词
- ENGLISH_LEXER --英文分词
- DEFAULT_LEXER --默认分词,中文最少分词
-- 查询jeecg模式下yangbo_test索引的分词 -- I 表:CTI$INDEX_NAME$I 用来保存分词结果 -- P 表:CTI$INDEX_NAME$P 用来保存基表发生的增量数据变化 -- N 表:CTI$INDEX_NAME$N 用来保存原表记录 rowid 和新记录条记 -- D 表 :CTI$INDEX_NAME$D 保存了所有的将被删除的 docid select * from jeecg.cti$yangbo_test$i select * from jeecg.cti$yangbo_test$n select * from jeecg.cti$yangbo_test$p select * from jeecg.cti$yangbo_test$d -- 使用全局索引 select * from "JEECG"."YB_TEST_WORD" where contains(word_test,'索引' and '单独' or '在') --全文索引更新 ALTER CONTEXT index cti_address on person.address rebuild; --查看全文索引 Select * from ctisys.syscontextindexes;
--创建全文索引
CREATE CONTEXT INDEX "yangbo_test" ON "JEECG"."YB_TEST_WORD"(word_test)
TABLESPACE "JEECG"
LEXER CHINESE_LEXER SYNC;
索引相关字典
select * from dba_indexes
索引注意事项
索引使用准则
- 使用下面的准则来决定何时创建索引:
- 如果需要经常地检索大表中的少量的行,就为查询键创建索引;
- 为了改善多个表的连接的性能,可为连接列创建索引;
- 主键和唯一键自动具有索引,在外键上很多情况下也创建索引;
- 小表不需要索引。
- 选取表中的索引列时可以考虑以下几点:
- 列中的值相对比较唯一 ;
- 取值范围大,适合建立索引;
- CLOB 和 TEXT 只能建立全文索引、BLOB 不能建立任何索引。
限制表中索引数量
一个表可以有任意数量的索引。但是,索引越多,修改表数据的开销就越大。当插入或删除行时,表上的所有索引也要被更改;更改一个列时,包含该列的所有索引也要被更改。因此,在从表中检索数据的速度和更新表的速度之间有一个折衷。例如,如果一个表主要仅用于读,则索引多就有好处;如果一个表经常被更新,则索引不宜多建。
预估索引大小和设置存储参数
创建索引之前先估计索引的大小能更好地促进规划和管理磁盘空间。可以用索引以及回滚段、重做日志文件的组合估计的大小来决定支持所期望的数据库所需的磁盘空间的大小。通过这些估计,就可以购买合适的硬件和做出其他正确的决定。
用单个索引估计的大小能更好地管理索引使用的磁盘空间。创建索引时,可以设置适当 的存储参数,并改善使用该索引的应用的 I/O 性能。例如,假设在创建索引之前估计索引的最大大小,之后就可以在创建该索引时设置适当的存储参数,就能很少为表的数据段分配簇。并且,所有的该索引的数据都被保存在相对连续的磁盘空间扇区中,这就减少了使用该索引的磁盘 I/O 操作所需的时间。
为索引指定表空间
可以在除临时表空间、日志表空间和回滚段表空间外的其他任何表空间中创建索引,也可以在其索引的表的相同或不同的表空间中创建索引。如果表及其索引使用相同的表空间 能更方便地对数据库进行管理(如表空间或文件备份)或保证应用的可用性,因为所有有关的数据总是在一起联机。然而,将表及其索引放在不同的表空间(在不同磁盘上)产生的性能比放在相同的表空间更好,因为这样做减少了磁盘竞争。但是将表及其索引放在不同的表空间时,如果一个表上某索引所在的表空间脱机了,则涉及这张表的 SQL 语句可能由于执行计划仍旧需要使用被脱机的索引而不能成功执行。
执行计划
执行计划是 SQL 语句的执行方式,由查询优化器为语句设计的执行方式,交给执行器去执行。在 SQL 命令行使用 EXPLAIN 可以打印出语句的执行计划。
一个执行计划由若干计划节点组成: 每一个计划节点包含操作符(cscn2, slct2..)和他的代价([1,856,280])等信息,代价由一个三元组组成[代价,记录行数,每行的字节数]
执行过程为:控制流从上向下传递,数据流从下向上传递。
--查找执计划节点操作符的字典 select * from v$sql_node_name
安全管理
审计分析
审计员:SYSAUDITOR
- 系统审计
系统的启动与关闭,此级别的审计记录在任何情况下都会强制产生,无法也无需由用户进行设置。
- 语句审计
导致影响特定类型数据库对象的特殊 SQL 或语句组的审计。如 AUDIT TABLE 将审计 CREATE TABLE、ALTER TABLE 和 DROP TABLE 等语句。
- 对象审计
审计作用在特殊对象上的语句。如 PERSON 表上的 INSERT, delete,update 语句。
审计开启
在 DM 系统中,启用审计功能需要两步
- 打开审计开关(默认审计开关是关闭),并重启数据库服务。
- 对审计对象设置审计条件,否则不记录审计
- 审计开关 --0 :关闭审计 1:打开普通审计 2:打开普通审计和实时审计,缺省值为 0 SP_SET_ENABLE_AUDIT(PARAM INT)
- 语句审计 --TYPE:审计对象(表,视图,存储过程) --Username:用户,null 表示不限制 --Whenever:审计时机 ALL: 不管成功或是失败都审计;SUCCESSFUL:操作成功的时候审计;FAIL:操作失败的时候审计
• SP_audit_stmt(type,username,whenever)
--例如:
SP_audit_stmt('TABLE','JEECG','ALL')
--查看审计
select * from v$auditrecords; 关闭语句级审计
Sp_noaudit_stmt(type,username,whenever)
Sp_noaudit_stmt(‘TABLE’,’TEST’,’ALL’);• 对象审计 --TYPE:审计对象(表,视图,存储过程)
--Username:用户,null 表示不限制
--schema_name:模式名
--object_name: 对象名
--column_name: 列名
--whenever :审计时机 ALL: 不管成功或是失败都审计;SUCCESSFUL:操作成功的时候审计;FAIL:操作失败的时候审计
Sp_audit_object(type, username, schema_name, object_name, column_name, whenever)
例如:sp_audit_object('UPDATE','TEST','TEST','EMP','SALARY','ALL'); 关闭对象级审计
Sp_noaudit_object(‘INSERT’,’TEST’,’TEST’,’EMP’,’SALARY’,’ALL);
- 关于审计设置的说明
- 只要审计功能被启用,系统级的审计记录就会产生。
- 在进行数据库审计的时候,审计员之间没有区别,可以审计所有数据库对象,也可以取消其他审计员的审计设置
- 语句级审计不针对特定的对象,只针对用户
- 对象级审计针对指定的用户与指定的对象进行审计。
- 在设置审计时,审计选项不区分包含关系,审计时机不区分包含关系,都可以设置
- 如果用户执行的一条语句与设置的若干审计项都匹配,只会在审计文件中生成一条审计记录。
数据库安全基线
账号和密码安全
select * from dba_users
- DBA:具有几乎所有权限(除审计和强制访问控制之外),默认赋给 SYSDBA 用户。
- PUBLIC:具有对当前模式下对象的 DML 数据操作权限。
- RESOURCE:具有在当前模式下数据定义权限(创建表、索引、视图等),
- SOI:具有查询 sys 开头系统表的权限
- VTI:具有查询 v$开头的动态视图权限
数据库版本升级
select id_code;
select * from v$instance;
select * from v$license;
select * from v$version
数据库监控
- 使用 DEM 来监控
- 使用./monitor 监控管理工具来监控
会话监控
select count(*) from v$sessions where state='ACTIVE';
select * from v$sessions where state='ACTIVE'
死锁监控
锁分为TID锁,对象锁,
共享锁 S,排他锁 X,意向锁 IX IS
select b.object_name,c.sess_id,a.* from v$lock a ,dba_objects b, v$sessions c
where a.table_id=b.object_id
and ltype='OBJECT'
and a.trx_id=c.trx_id
sql语句监控
select *from v$sql_history
表空间监控
select * from v$DATAFILE
select * from dba_data_files
资源监控
达梦数据加载
dmfld(DM Fast Loader)是 DM 提供的快速数据装载命令行工具。用户通过使用 dmfldr 工具能够把按照一定格式排序的文本数据以简单、快速、高效的方式载入到 DM 数据库中,或把 DM 数据库中的数据按照一定格式写入文本文件。
# 数据文件
1,aaaaa,2022-04-21
2,bbbbb,
3,cccc,2021-11-11
#控制文件
LOAD DATA
INFILE '/dm8/fldr/fldrtest.txt'
INTO TABLE TEST.FLDRTEST
FIELDS ','
#创建表
create table jeecg.yangbo_fast(id int, name varchar(20), bir date);
# 批量加载
./dmfldr sysdba/dameng123 control=\'/dm8/fldr/fldrtest.ctl\'
• 大字段导入导出 create table test.dtoutput(c1 int, c2 blob, c3 clob);
insert into test.dtoutput values(1,0XAB1211032DE,'THIS IS A dmfldr test');
[dmdba@localhost fldr]$ cat dtfldr.ctl
LOAD DATA
INFILE '/dm8/fldr/dtfldr.txt'
INTO TABLE TEST.DTOUTPUT
FIELDS '|'
#导出
[dmdba@localhost bin]$ ./dmfldr sysdba/dameng123 control=\'/dm8/fldr/dtfldr.ctl\' lob_directory=\'/dm8/fldr\' mode=\'out\'
# 导出后,导入
[dmdba@localhost fldr]$ cat dtfldr.ctl LOAD DATA INFILE '/dm8/fldr/dtfldr.txt' INTO TABLE TEST.DTINPUT FIELDS '|' (C1, C2, C3)
• 案例三 #1、创建数据文件
[dmdba@localhost fldr]$ cat test2.txt ID,NAME 1,AAAA 2,BBBB 34,dddddd
#2、创建表
create table test.t50(id int, name varchar(20));
#3、创建控制文件
[dmdba@localhost fldr]$ cat test2.ctl
options( skip=1 )
LOAD DATAINFILE '/dm8/fldr/test2.txt'
INTO TABLE TEST.T50
FIELDS ','
#4、加载数据
• [dmdba@localhost bin]$ ./dmfldr sysdba/dameng123 control=\'/dm8/fldr/test2.ctl\' badfile=\'/dm8/fldr/test2.bad\
性能优化
内存管理
- 共享内存池 select * from v$dm_ini where para_name like '%MEMORY%' Memory_target:指定单个共享内存池的目标大小
Memory_pool: 指定单个共享内存池的初始大小
Memory_extent_size:提定单个共享内存池的增量大小
Memory_N_pool:指定多个共享内存池 - 缓冲区
- 数据缓冲区
- normal(buffer)
- keep
- fast
- recycle
- 日志缓冲区
主要存储redo日志
RLOG_BUF_SIZE
- 字典缓冲区
DICT_BUF_SIZE
- sql缓冲区 select * from v$dm_ini where para_name like '%cache_pool_size%'
- 运行时内存池
- 会话内存池
- 虚拟机内存池
- 排序区和哈希区
后台的进程和线程
达梦是单进程多线程的,每一个实例只有一个进程
v$process 进程字典
v$threads 线程字典
sql执行的过程
- 语法分析(字典缓冲区)
- 语义分析(字典缓冲区)
- 权限判断(字典缓冲区)
- 是否存在执行计划( sql缓冲区,buffer)
- 执行sql,结果缓冲到sql缓冲区,(sql缓冲区,排序区,哈希区,buffer)
sql优化
--等于1时,et可以使用
select * from v$dm_ini where para_name = 'enable_monitor'
select * from v$dm_ini where para_name = 'monitor_sql_exec'
call et(执行号)
awr报告
SYS.WRM$_WR_CONTROL 记录快照的相关控制信息。 Sys.wrm$_snapshot 记录快照的相关信息
- 初始化awr快照包
--查看awr是否创建
select sf_check_awr_sys;
--初始化awr包
sp_init_awr_sys(1);
--创建快照包的间隔时间(分钟)
call dbms_workload_repository.awr_set_interval(10);
--手动生成快照
call dbms_workload_repository.create_snapshot();
--查询快照
select * from sys.wrm$_snapshot;
--生成awr报告
call sys.awr_report_html(1,4,'/dm8','awr1.html');