DB2 10.5引入列式存储表技术,作为DW数据应用的特性,对性能具有很大的提升,同时对SQL基本不做索引优化,查询时直接可以按照列存储格式查询相关列即可,可以说管理很简单了。作为一个新特性,DB2 LUW V10.5的列式组织表功能依然作为一个可选择功能项,用户可以按照自己数据库业务的特点,选择是否启用该功能,对于升级到DB2 LUW V10.5的数据库环境来说,需要经过同样的参数配置,也可以支持这个功能。
在创建数据库前,在DB2 V10.5实例提供了注册变量选项值,即DB2_WORK_LOAD新增可配置值ANALYTICS,配置改参数值后,DB2会为新创建的分析性工作负载数据库建立最佳缺省配置,启用改参数后,数据库会自动配置如下参数,也是支持和影响列式存储环境的几个关键参数:
dft_table_org该参数指定创建表的默认类型,通常设定为row,启用ANALYTICS注册变量值后,系统会自动配置为column
dft_degree 指定分区内SQL语句的并行度,该参数会被自动配置为any
dft_extent_sz 缺省表空间的扩张块大小,该参数会自动被设置为4(默认值为32)
catalogcache_sz 即目录高速缓存,该参数会被自动设置为比通常数据库类型的默认值更大的值
util_heap_sz 即实用程序堆大小,该参数会被自动配置为一个用于装载列组织表时所需额外内存的大小
auto_reorg 即自动重组操作,该参数会被配置为on
sortheap(排序堆)和sheapthres_shr需要根据实际计算配置
当然,如果在已经创建好的数据库库后才对DB2_WORK_LOAD注册变量参数配置analytics,当数据库运行autoconfigure也具有相同效果
创建列组织表
那么如何创建DB2列组织表呢?其实创建列组织表和创建普通行式组织表的语句大体相同,只是列式组织表在creat table后添加了ORGANIZE BY COLUMN的语句。当然如果你当前的数据库级的配置参数dft_table_org设置为column的话,也可以不使用organize by column语句选项,因为在启用该参数值的数据库中,创建的表默认就是列组织表类型,如下是一个创建列组织表的示例DDL:
CREATE TABLE "DB2INST1"."EMPLOYEE" (
"EMPNO" CHAR(6 OCTETS) NOT NULL ,
"FIRSTNME" VARCHAR(12 OCTETS) NOT NULL ,
"MIDINIT" CHAR(1 OCTETS) ,
"LASTNAME" VARCHAR(15 OCTETS) NOT NULL ,
"WORKDEPT" CHAR(3 OCTETS) ,
"PHONENO" CHAR(4 OCTETS) ,
"HIREDATE" DATE ,
"JOB" CHAR(8 OCTETS) ,
"EDLEVEL" SMALLINT NOT NULL ,
"SEX" CHAR(1 OCTETS) ,
"BIRTHDATE" DATE ,
"SALARY" DECIMAL(9,2) ,
"BONUS" DECIMAL(9,2) ,
"COMM" DECIMAL(9,2) )
IN "USERSPACE1"
ORGANIZE BY COLUMN;
行组织表与列组织表的转换
那么对于创建时没有指定列式组织或者由低版本升级的数据库中的行式组织表,如何将其转换成列式组织表呢?DB2 V10.5充分考虑了用户需求,提供了一个新的实用程序工具db2convert,用于将行式组织表转换为列式组织表,如下依然以db2inst2.employee表为例,将其转换为列式组织表,获取到的原始表的DDL语句如下:
CREATE TABLE"DB2INST2"."EMPLOYEE" (
"EMPNO" CHAR(6 OCTETS) NOT NULL ,
"FIRSTNME" VARCHAR(12 OCTETS) NOT NULL ,
"MIDINIT" CHAR(1 OCTETS) ,
"LASTNAME" VARCHAR(15 OCTETS) NOT NULL ,
"WORKDEPT" CHAR(3 OCTETS) ,
"PHONENO" CHAR(4 OCTETS) ,
"HIREDATE" DATE ,
"JOB" CHAR(8 OCTETS) ,
"EDLEVEL" SMALLINT NOT NULL ,
"SEX" CHAR(1 OCTETS) ,
"BIRTHDATE" DATE ,
"SALARY" DECIMAL(9,2) ,
"BONUS" DECIMAL(9,2) ,
"COMM" DECIMAL(9,2) )
IN "USERSPACE1"
ORGANIZE BY ROW;
为了便于观察过程,我们最好为其导入数据,有一定的数据量,以便于观察转换过程,此测试数据来源都是DB2示例数据库sample中相关表中获取的,在此就不多讲,读者可以自己自行测试效果。
如此,我们就可以对其进行转换,其实db2convert工具的用法相对简单,可以进行整库转换,也可以指定单表,需要提供表的schema和tablename,具体用法可以参阅相关使用说明:
[db2inst1@dblab test]$ db2convert -d sample -z db2inst2 -t employee
Proceeding with the conversion...
Table RowsNum RowsComm Status Progress (%)
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 42 0 UNSTARTED 0.00
Table RowsNum RowsComm Status Progress (%)
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 42 0 UNSTARTED 0.00 Table RowsNum RowsComm Status Progress (%)
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 42 0 INIT 0.00 Table RowsNum RowsComm Status Progress (%)
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 42 0 INIT 100.00 Table RowsNum RowsComm Status Progress (%)
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 42 0 INIT 100.00 Table RowsNum RowsComm Status Progress(%)
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 42 0 COPY 0.00 Table RowsNum RowsComm Status Progress(%)
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 42 0 COPY 0.00 Table RowsNum RowsComm Status Progress(%)
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 42 0 COPY 0.00
Table RowsNum RowsComm Status Progress(%)
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 42 0 COPY 100.00
Table RowsNum RowsComm Status Progress(%)
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 42 0 COPY 100.00 Table RowsNum RowsComm Status Progress (%)
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 0 0 REPLAY 100.00
Table RowsNum RowsComm Status Progress (%)
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 0 0 REPLAY 100.00
Table RowsNum RowsComm Status Progress(%)
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 0 0 SWAP 0.00
Table RowsNum RowsComm Status Progress(%)
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 0 0 SWAP 100.00
Final Summary:
Table RowsNum InitSize(MB) FinalSize (MB) CompRate (%) State
--------------------------------------- --------------- ---------------
"DB2INST2"."EMPLOYEE" 42 0.50 10.25 -1950.00 Completed
Pre-Conversion Size (MB): 0.50
Post-Conversion Size (MB): 10.25
Compression Rate (Percent): -1950.00
SQL2446I The db2convert command completed successfully. Allrow-organized tables that satisfy the specified matching criteria have beenconverted to column-organized tables.
可以看到db2convert整个过程其实是基于admin_move_table的原理实现,整个过程也是对表在线做的类型转换。另外注意的是,范围分区表,MDC表和ITC表默认是不能被转换成列式组织表的,需要在上面的命令中使用-force选项才可以执行该命令进行转换。在转换前表存在的依赖对象最好能够删掉,外键约束会影响转换的时间,最重要的一点就是表的类型转换操作在线是不可逆的,所以建议最好在转换成列式组织表前对相关表或者对转换库做完整的备份。
db2convert -d sample
可以将数据库sample中所有的行式组织表转换成列式组织表。
重组列式组织表
在日常维护和使用列式组织表也需要定期对数据量增删操作比较频繁的表进行重组,以便于提高运程序的查询的执行性能,当然如果启用了auto_reorg参数,数据库会自动对相关列组织表进行重组操作,如果手动重组列组织表只需要在reorg table命令后面加上RECLAIM EXTENTS选项即可,如下演示了列式表的重组操作:
[db2inst1@dblab test]$ db2 reorgtable db2inst2.employee RECLAIM EXTENTS
DB20000I The REORG command completedsuccessfully.
如果不加该选项的手动重组的话,对于列式组织表的重组会有如下报错信息:
[db2inst1@dblab test]$ db2 reorgtable db2inst2.employee
SQL2216N SQL error "-1667"occurred while reorganizing a database table or its indexes.
解释执行计划
列式组织表的统计信息收集方法与普通的行式组织表相同,在此就不介绍。对于列式组织表的访问,通过如下的示例SQL,可以看到执行计划也会发生相应:
示例SQL:
SELECT
EMPNO,
ACTNO,
CHAR(EMSTDATE, USA),
CHAR(EMENDATE, USA)
FROM
DB2inst1.EMPPROJACT
WHERE
EMPNO IN
(SELECT
EMPNO
FROM
db2inst1.EMPLOYEE
WHERE
WORKDEPT='E11'
)
新的 CTQ 计划运算符表示列组织数据处理与行组织数据处理之间的转变,捕获列组织表说明信息的步骤与用于针对行组织表运行性能查询的步骤相同。
db2 set current explain mode explain
执行测试SQL语句
db2exfmt -d sample -1 -o output.exfmt
获取的执行计划信息如下:
Access Plan:
-----------
Total Cost: 71.9656
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
12.1667
CTQ
( 2)
71.9656
10.5689
|
12.1667
HSJOIN
( 3)
71.9606
10.5689
/-------+-------\
73 7
TBSCAN TBSCAN
( 4) ( 5)
40.1348 31.8243
5.89474 4.67416
| |
73 42
CO-TABLE: DB2INST1 CO-TABLE:DB2INST1
EMPPROJACT EMPLOYEE
Q2 Q1
可以看到,对列式组织表访问多了一个叫CTQ的访问计划,表示将数据从按行组织的数据处理传递至按列组织的数据处理的按列组织的表队列。并且从CO-TABLE信息可以判定,两表均为列组织表,以上是一个简单的执行计划,当然实际应用SQL比较复杂,但是通过这些信息还是可以判断的,在此就不做详细的案例分析。