草草写了一篇所学习到的一些DB2技术和经验的日志,当然这些只是其中小部分.会继续分享的

----------------------------------------

表设计时需要注意的:

    1.       默认值

create table tbname(col1 int not null with default 1)  或者

create table tbname(col1 int not null default 1)

使用了该默认值可以

    2.       Char和varchar

字段数据类型尽量使用char来代替字符,char类型性能稍比varchar好点。因为varchar是变长类型,所以是先读取数据长度再读取数据,分了两个步骤,而char是定长类型,读取数据长度和数据只用了一个步骤

    3.       字段顺序

如果该表常常更新且字段中含有varchar数据类型,请把该字段放到最后。

(1)create table tbname(col1 int not null with default 1,col3 varchar(10),col2 int)【不推荐】

(2)create table tbname(col1 int not null with default 1,col2 int,col3 varchar(10))【推荐】

原因是varchar类型是变长的,而char是定长的,所以常常见到在读char类型的时候,不足所指定长度的数据则补充空格.因为是变长的类型所以字段在CREATE表的时候列col3会在按CREATE顺序来创建,但在(1)中列col3不会直接是varchar,而是DB2把列col3的值移到最后面,而在col3只保存一个定长的指针指向到最后的值而已.在(2)中只要直接把变长的类型字段放置最后面即可避免DB2额外生成多一个指针.

    4.       合适使用约束也可以增强查询性能

Create table tbname(col1 int ,col2 int,col3 int generated always as(col1 + col2),col4 int generated always as( case when col1 > col2 then col1 else col2 end))

         查询1 取col1和col2之和的时候

         Select sum(col1+col2) from tbname;

         可以改成:

         Select sum(col3) from tbname;

         查询2 取col1和col2其中最大的一个

         Select case when col1 > col2 then col1 else col2 end as col from tbname

         可以改成

         Select col4 as col from tbname;

一些常用的技巧

1.删除大量数据的时候

删除表中数据:delete from tablename

不记 log 删除表中数据: alter table tabname activate not logged initially;delete from tablename

修改表不记录 log 方式:alter table tabname activate not logged with empty table

LOAD 的 replace 方式:load from empfile of del replace into tabname

======

以上四种用法参考了袁春光在DW上发布的的文章[LOAD的使用技巧].

注:对于存放敏感数据的表不推荐这样使用,因为把日志删除后,数据就很难恢复回来了.

2.变量赋值

  (1)在存储过程或者函数(function)中常见如下赋值:

Begin atomic
default
 default 0;
default
           declare val4 char;
           set val1 = 1;
           set val2 = 1;
           set val3 = 1;
           set val4 = ‘1’;
  End;

         (2)可以改写成以下形式:

 

Begin atomic
           declare val1 int default 0;
           declare val2 int default 0;
           declare val3 int default 0;
                   declare val4 char(2);
                   declare val5 char(2) default null;

                   --含变量赋值的时候使用如下

                   -- values(1,1,1,coalesce(val5,’1’)) into val1,val2,val3,val4; //假设在设val4的是变量最好加上一个避免空值的coalesce来控制,因为values(…) into(…) 的时候有空值会报错

                   --只含常量的时候推荐使用如下

values(1,1,1,coalesce(val5,’1’)) into val1,val2,val3,val4;

         End;

         这样的赋值的好处有提高性能,减低代码量:因为按照(1)形式来编写的时候每set一次,DB2都会去访问一次内存,其实是很影响性能的,而values 一次就能把所有需要赋的值的指针全部找出来,理论说(2)的形式能提高(1)的形式的n-1次set的倍性能

3.count(*) 和exists的用法

在判断数据是否存在的时候尽量避免使用count(1),因为这样会对全表遍历可以使用exists来代替,exists的好处是它一旦遇到数据就立刻终止查询下去

例:

select case when count(1) >0 then '存在'  else '不存在'  end as isFlag from test fetch first 1 row only;

可以改写成

select case when exists(select 1 from test fetch first 1 row only) then '存在'  else '不存在'  end as isFlag from test fetch first1 row only;

--该方式写得比较复杂,但是主要为了举例说明exists的用法

4.DB2的编写风格建议

根据本人实践了牛新庄的经验总结,了解到DB2中的SQL优化器对复杂的SQL优化得比较强大(相对于oracle来说),建议尽量的编写一条复杂的SQL来代替多条的简单SQL.

例:要求你把客户ID为123的客户名称 张三改成李四,并且把他更改前和更改后的数据查询出来

1:一般情况下会有如下步骤:

  (1)     查询更改前的客户信息

Select cid,cname from customer where cid=123;

  (2)     更改客户姓名

Update customer set cname=’李四’ where cid=123;

  (3)     查询更改后的客户信息

Select cid,cname from customer where cid=123;

2:可以更改成该用法

Select cid,cname from new table(Update customer set cname=’李四’ where cid=123);

with t1 as (Select cid,cname from new table(Update customer set cname=’李四’ where cid=123))

select * from t1 where cid=123 union all select * from customer where cid=123 with ur;

         以上的写法没有在业务逻辑上修改,但性能增加一倍以上