ITPub博客

首页 > Linux操作系统 > Linux操作系统 > SQL访问规范

SQL访问规范

原创 Linux操作系统 作者:DataKW 时间:2013-05-19 22:56:01 0 删除 编辑

SQL访问规范

5.1、避免SELECT *

程序中不能出现SELECT*,即使是选择全部选择项,也需要全部指明,这主要出于如下原因:第一:使用*相对比较慢,因为Oracle需要遍历更多的内部字典信息;第二:为避免以后相关表增加字段造成程序错误,比如INSERT INTO SELECT和SELECT INTO语句会报错;

5.2、避免笛卡尔运算

多表关联查询不能出现笛卡尔积,如果在报表中为集聚表(或称中间表)生成多个维度组成的复合主键需要使用迪克尔积的,必须请数据组确认性能。

5.3、使用CTAS备份

在进行DML操作(INSERT,UPDATE,DELETE)之前,必须对数据进行备份,使用如下语句:

方法一:表数据全部备份:

CREATE TABLE TAB_NAME_BAK AS SELECT * FROM TAB_NAME;

方法二:部分备份:对大表仅备份将要修改的数据:

CREATE TABLE TAB_NAME_BAK

AS SELECT * FROM TAB_NAME WHERE [选择出被操作数据的条件];

5.4、INSERT时需写全列名

代码中INSERT语句必须写出全部列名,以保证表增加字段后语句执行不受影响:

如:INSERT INTO TAB(COL1,COL2)VALUES(COL1_VAL,COL2_VAL);

再如:

INSERT INTO TAB(COL1,COL2)

SELECT COL1_VAL,COL2_VAL FROM TAB_BB;

不能将COL1,COL2和COL1_VAL,COL2_VAL省略;

5.5、大数据量的DML

DML操作涉及到大数据量时,请分解为多次执行;

对于UPDATE和DELETE每次涉及数据量在1万条左右,并且每次执行完就提交;

对于INSERT INTO SELECT如果采用提示(/*+ append parallel */)可以处理百万级别的数据量。

5.6、完成事务及时commit

对于一个完成了的事务,请用commit显示提交,这是避免锁争用的锁等待的需要,特别是对DML操作频繁的表;

5.7、java的变量绑定

使用“变量绑定”来处理一条SQL带不同常量多次执行的情况,动态绑定可以大大优化SQL的执行效率,还可以优化Oracle的内存使用。

在Java中,结合使用setXXX 系列方法,可以为不同数据类型的绑定变量进行赋值,从而大大优化了SQL 语句的性能。

JAVA情况下的动态绑定示例如下:

String v_id = 'xxxxx';

String v_sql = 'select name from tb_a where id = ? ';

stmt = con.prepareStatement( v_sql );

stmt.setString(1, v_id ); //为绑定变量赋值

stmt.executeQuery();

5.8、perl的变量绑定

使用“变量绑定”来处理一条SQL带不同常量多次执行的情况,动态绑定可以大大优化SQL的执行效率,还可以优化Oracle的内存使用。

PERL绑定变量实例如下:

$modsql = qq{

    insert into tmp_tai_rtkpi_mark

    (tab_name,

     kpi_id,

     ne_id,

     timepoint,

     cacu_time,

     start_time,

     stop_time,

     down_base,

     up_base,

     ajast_flag,

     inuse_flag,

     cal_data)

    values

    (?,?,?,?,?,?,?,?,?,?,?,?)

};

if ( !$dbh->prepare($modsql) ) {

    writeToLog( "start SQL prepare Error!/n" . DBI::errstr . "/n/n" );

}

$sth_msg_in_DB = $dbh->prepare($modsql)

  || die( "start SQL prepare Error!/n" . $DBI::errstr . "/n" );

 

$sth_msg_in_DB->bind_param( 1,  $kpiid_tab{$kpi_id} );

$sth_msg_in_DB->bind_param( 2,  $kpi_id );

$sth_msg_in_DB->bind_param( 3,  -1 );

$sth_msg_in_DB->bind_param( 4,  -1 );

$sth_msg_in_DB->bind_param( 5,  $current_time );

$sth_msg_in_DB->bind_param( 6,  $start_time );

$sth_msg_in_DB->bind_param( 7,  $end_time );

$sth_msg_in_DB->bind_param( 8,  $temp_min );

$sth_msg_in_DB->bind_param( 9,  $temp_max );

$sth_msg_in_DB->bind_param( 10, 0 );

$sth_msg_in_DB->bind_param( 11, 1 );

$sth_msg_in_DB->bind_param( 12, -1 );

$sth_msg_in_DB->execute() || die( "SQL Execute Error!/n" . $DBI::errstr . "/n" );

5.9、避免重复访问:使用group

避免重复访问(一):同源单组单查询:

如下语句要避免:

SELECT  CLASS,sum(COL) FROM  TAB_TEST  WHERE CLASS=’A’ UNION ALL

SELECT  CLASS,sum(COL) FROM  TAB_TEST  WHERE CLASS=’B’ UNION ALL

SELECT  CLASS,sum(COL) FROM  TAB_TEST  WHERE CLASS=’C’

改写成:

SELECT CLASS,sum(COL) FROM TAB_TEST GROUP BY CLASS

5.10、避免重复访问:竖向显示变横向现实

避免重复访问(二):竖向显示变横向显示

问题语句:

SELECT A.C1 AC1,A.C2 AC2,A.C3 AC3,

       B.C1 BC1,B.C2 BC2,B.C3 BC3,

       C.C1 CC1,C.C2 CC2,C.C3 CC3

FROM

  (SELECT '123' X, 'SYNONYM' C1, sum(2) C2,count(1) C3 

     FROM TAB WHERE TABTYPE = 'SYNONYM') A,

  (SELECT '123' X,'TABLE'   C1, sum(2) C2,count(1) C3 

     FROM TAB WHERE TABTYPE = 'TABLE') B,

  (SELECT '123' X,'VIEW'   C1, sum(2) C2,count(1) C3 

     FROM TAB WHERE TABTYPE = 'VIEW') C    

;

 

正确使用形式如下:

SELECT MAX(DECODE(TABTYPE,'SYNONYM','SYNONYM',NULL))  AC1,

       MAX(DECODE(TABTYPE,'SYNONYM',sum(2),0)) AC2,

       MAX(DECODE(TABTYPE,'SYNONYM',count(1),0)) AC3,

       MAX(DECODE(TABTYPE,'TABLE','TABLE',NULL))  BC1,

       MAX(DECODE(TABTYPE,'TABLE',sum(2),0)) BC2,

       MAX(DECODE(TABTYPE,'TABLE',count(1),0)) BC3,

       MAX(DECODE(TABTYPE,'VIEW','VIEW',NULL))  CC1,

       MAX(DECODE(TABTYPE,'VIEW',sum(2),0)) CC2,

       MAX(DECODE(TABTYPE,'VIEW',count(1),0)) CC3      

FROM TAB

WHERE TABTYPE IN('TABLE','SYNONYM','VIEW')

GROUP BY TABTYPE;

5.11、避免重复访问:用表更新表

避免重复访问(三):一个表同时更新另一个表的多个字段

问题SQL:使用TB_SOURCE表更新表TB_TARGET的多个字段

UPDATE  TB_TARGET  A  SET  

A.COL1 = (select B.COL1 from TB_SOURCE  B where B.id = A.id) ,

A.COL2 = (select B.COL2 from TB_SOURCE  B where B.id = A.id) ,

A.COL3 = (select B.COL3 from TB_SOURCE  B where B.id = A.id) ,

A.COL4 = (select B.COL4 from TB_SOURCE  B where B.id = A.id)

WHERE A.id IN ( select B.id from TB_SOURCE B)

正确使用形式如下:

UPDATE  TB_TARGET  A 

SET  (COL1, A.COL2, A.COL3, A.COL4 )=(SELECT B.COL1, B.COL2, B.COL3, B.COL4

FROM TB_SOURCE B  WHERE B.id = A.id)

WHERE EXISTS (select 1 from TB_SOURCE B where B.id = A.id)

5.12、数据库连接及时关闭

程序中必须显示关闭数据库连接,不仅正常执行完后需显示关闭,而且在异常处理块(例如java的exception段)也要显示关闭。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/27573546/viewspace-761477/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 索引的设计规范
下一篇: 实施规范
请登录后发表评论 登录
全部评论

注册时间:2012-08-12

  • 博文量
    132
  • 访问量
    331527