技术开发 频道

应用系统优化之DM垂直分区

  【IT168 技术文档】随着数据库应用规模的扩展,需要管理的数据规模也越来越大,普通的数据库查询优化机制在某些情况下已不能满足性能要求了。利用数据库分区技术,可以有效减少I/O量,提升系统查询性能。文章描述了DM(达梦)数据库管理系统垂直分区的实现原理和使用限制,并举例说明了垂直分区的使用,为应用系统的优化提供参考。

  1.垂直分区简介

  数据库分区是一种物理数据库设计技术,其主要目的是为了在特定的SQL操作中减少数据读¬写的总量以缩减响应时间。垂直分区通过对表的垂直划分来减少目标表的宽度,使某些特定的列被划分到特定的分区,每个分区都包含了其中的列所对应的行。

  DM数据库管理系统提供了垂直分区功能,供数据库管理员和应用开发人员使用,以优化系统的性能。本文主要目的是解释DM数据库管理系统垂直分区的实现思路,以及使用限制的说明,供数数据库管理员和应用开发人员参考。

  2. DM垂直分区实现说明

  DM数据库管理系统中,垂直分区的实现方式是:将垂直分区表分拆成多个表,每个表包含较少的列。定义一个垂直分区表,系统将自动为其创建一个分区基表和若干个分区子表。分区基表不保存实际数据,只保存表定义、分区信息,实际数据保存在分区子表中。

  每个分区子表包含定义的分区子表列和CLUSTER PK列。并且,在所有的分区子表上建立了CLUSTER PK索引。这样拆分后,每个子表只包含较少列数据,通过CLUSTER PK列进行行匹配,各个分区子表中的每个逻辑行与其他分区子表的相同逻辑行匹配,可以方便的还原主表定义的完整数据。

  2.1 数据修改的实现

  分区子表,对用户是透明的,用户操作的对象是分区基表,但实际数据是存放在分区子表中的。因此,系统内部必须将用户对分区基表的数据修改,映射到各个分区子表上。

  数据插入,由于分区子表只包含部分列,因此,系统在插入数据过程中,为每个分区子表从输入的分区基表数据中提取出需要的数据,并重新构造符合分区子表格式的记录,插入到每个分区子表。

  数据更新,如果被更新列是CLUSTER PK列,那么系统将在所有分区子表中删除对应的数据行,并根据新值构造相应的记录,重新插入分区子表。如果被更新列不是CLUSTER PK列,那么系统首先确定更新列对应的分区子表,并只对相应的分区子表做修改。

  数据删除,删除分区基表的一行数据,需要将其所有分区子表上对应的行删除。

  2.2 数据还原实现

  实现垂直分区表,还要考虑的一个问题是,如何保证垂直分区表的数据完整性和一致性。由于实际数据是存放在各个分区子表中的,基表中并没有任何数据,因此存在一个数据还原的过程――根据分布在不同分区子表中的数据,重新组织出与基表定义一致的数据。

  为了还原基表数据,DM数据库管理系统,使用了虚表技术――根据垂直分区表的定义,系统内部为垂直分区基表构造了一个虚表。虚表实现上类似于视图,包含表的列信息、约束信息以及分区信息,还包含类似于视图的查询SQL脚本,对分区子表上的CLUSTER PK列做等值查询,从各个分区子表获取数据,以重新构造出基表的数据行。

  2.3 分区指定实现

  垂直分区的主要目的是,使查询得以扫描较少的数据,减少I/O量,从而提高查询性能。例如,某个表包含七列,通常只引用该表的前三列,那么将该表的后四列拆分到一个单独的表中将有利于提高查询性能。

  一旦查询中使用到垂直分区表,系统判断查询需要的数据是否只涉及某个分区子表,如果是,直接使用分区子表替代分区基表,进行查询优化。系统只需以较少的I/O代价,即可获得需要的数据。如果数据是分布在多个分区子表中,系统使用2.2数据还原实现描述的虚表,替换分区基表,进行查询优化。这样的处理对用户来说是完全透明的。

  通过分区指定,系统可自动选择代价较少的查询路径,提高系统性能。

  3.DM垂直分区语法说明

  DM数据库管理系统通过PARTITON子句提供垂直分区功能,语法式如下:

CREATE  TABLE <表名定义>
(
<列定义> {,<列定义>} {,<表级完整性约束>})
[]
[<空间限制子句>]
[];
……
::
= PARTITION BY
::
=
RANGE (
<列名>) [LEFT | RIGHT] FOR VALUES ( {,})
| HASH (<列名>) PARTITIONS <分区数> [STORE IN (<文件组列表>)]
| COLUMN ((<列名> {,<列名>}){,(<列名> {,<列名>})})
……

  4.DM垂直分区使用限制

  垂直分区表的主表不包含实际数据,实际数据存放在垂直分区子表中。对用户来说,垂直分区表和普通表是没有任何区别的,用户可以像使用普通表一样使用垂直分区表。但用户应谨慎考虑垂直分区操作,因为分析多个分区内的数据需要查询连接这些表。如果分区过大的话,可能会影响性能。

  同时,垂直分区也不是适合任何应用场景,垂直分区的使用也存在一定的限制,DM垂直分区的使用存在如下限制:

  1. 建立垂直分区表必须要有CLUSTER PK,并且此聚集索引不允许删除

  2. 除PK列外,其他任何列只能出现在一个分区子表中

  3. 包含IDENTITY列的表不允许定义垂直分区

  4. 垂直分区表不允许建立触发器

  5. 垂直分区表不允许建立CHECK约束

  6. 垂直分区子表不允许建立索引

  7. 不允许跨分区定义索引

  8. 一张表最多允许定义8个垂直分区

  9. 由于DM系统中,大数据对象的实现已进行了优化,数据是保存在大数据对象从表中;因此,包含BLOB/CLOB列的表不允许定义垂直分区

  5.举例说明

  5.1 创建垂直分区表

CREATE TABLE TT(C1 INT CLUSTER PRIMARY KEY, C2 INT, C3 VARCHAR(100), C4 VARCHAR(300)) PARTITION BY COLUMN(C2);

  系统内部将创建3张表,分别是垂直分区基表TT,垂直分区子表TT0DMPART和TT1DMPART。分区子表的命名规则是,在主表名之后附加后缀NDMPART,其中N为0、1、2…。

  5.2 查看表定义

  调用系统函数TABLEDEF,查看系统创建的3张表定义如下:

SELECT TABLEDEF('SYSTEM', 'SYSDBA', 'TT');
CREATE TABLE
"TT" AT "SYSTEM"(
"C1" INTEGER NOT NULL,
"C2" INTEGER,
"C3" VARCHAR(100),
"C4" VARCHAR(300),
CLUSTER PRIMARY KEY(
"C1"))
PARTITION BY COLUMN((
"C1", "C2"), ("C1", "C3"))
SELECT TABLEDEF(
'SYSTEM', 'SYSDBA', 'TT0DMPART');
CREATE TABLE
"TT0DMPART" AT "SYSTEM"(
"C1" INTEGER NOT NULL,
"C2" INTEGER,
CLUSTER PRIMARY KEY(
"C1"))
SELECT TABLEDEF(
'SYSTEM', 'SYSDBA', 'TT1DMPART');
CREATE TABLE
"TT1DMPART" AT "SYSTEM"(
"C1" INTEGER NOT NULL,
"C3" VARCHAR(100),
"C4" VARCHAR(300),
CLUSTER PRIMARY KEY(
"C1"))

  可以看到系统自动创建的分区子表,都包含了CLUSTER PK列C1,C2列位于分区子表TT0DMPART中,而C3,C4列位于分区子表TT1DMPART中。

  5.3 查看查询计划

EXPLAIN SELECT * FROM TT;
#RSET:
[0, 1, 0];
    #XNLP:
[0, 1, 0]; CROSS_JOIN
        #CSEK:
[2, 1, 0]; INDEX33560184(TT1DMPART), FULL_SCAN
        #CSEK:
[0, 0, 0]; INDEX33560183(TT0DMPART), INDEX_EQU_SEARCH
EXPLAIN
SELECT C2 FROM TT;
#RSET:
[2, 1, 0];
    #CSEK:
[2, 1, 0]; INDEX33560183(TT0DMPART), FULL_SCAN
EXPLAIN
SELECT C2 FROM TT WHERE C1 = 1;
#RSET:
[0, 0, 0];
    #CSEK:
[0, 0, 0]; INDEX33560183(TT0DMPART), INDEX_EQU_SEARCH

  分析上述查询计划,可以获知,如果查询列只涉及某个分区子表情况下,系统只需要扫描特定的分区子表数据。由于分区子表中包含的数据比分区前少的多,因此可以极大的减少扫描物理页的数量,从而提升系统性能。

  但是,当查询列分布在不同分区子表中,系统需要通过连接查询,从分区子表中获取数据,这将对系统性能产生负面影响。

  因此,用户应该根据实际应用情况,科学划分,慎重使用垂直分区来提升系统性能。

0
相关文章