SQL 编程规范

一、sql书写规范:

二、书写优化性能建议

三、其他经验性规则

 

一、sql书写规范:

1、sql语句的所有表名、字段名全部小写,系统保留字、内置函数名、sql保留字大写。

2、连接符or、in、and、以及=、<=、>=等前后加上一个空格。

3、对较为复杂的sql语句加上注释,说明算法、功能。

注释风格:注释单独成行、放在语句前面。 
(1) 应对不易理解的分支条件表达式加注释; 
(2) 对重要的计算应说明其功能; 
(3) 过长的函数实现,应将其语句按实现的功能分段加以概括性说明; 
(4) 每条SQL语句均应有注释说明(表名、字段名)。 
(5) 常量及变量注释时,应注释被保存值的含义(必须),合法取值的范围(可选) 
(6) 可采用单行/多行注释。(-- 或 /* */ 方式)

4、SQL语句的缩进风格

(1) 一行有多列,超过80个字符时,基于列对齐原则,采用下行缩进 
(2) where子句书写时,每个条件占一行,语句令起一行时,以保留字或者连接符开始,连接符右对齐。

5、多表连接时,使用表的别名来引用列。

6、供别的文件或函数调用的函数,绝不应使用全局变量交换数据;

如例(1)


二、书写优化性能建议

1、避免嵌套连接。例如:A = B and B = C and C = D

2、where条件中尽量减少使用常量比较,改用主机变量

3、系统可能选择基于规则的优化器,所以将结果集返回数据量小的表作为驱动表(from后边最后一个表)。

4、大量的排序操作影响系统性能,所以尽量减少order by和group by排序操作。

如必须使用排序操作,请遵循如下规则:

(1) 排序尽量建立在有索引的列上。 
(2) 如结果集不需唯一,使用union all代替union。

5、索引的使用。

(1) 尽量避免对索引列进行计算。如对索引列计算较多,请提请系统管理员建立函数索引。 
(2) 尽量注意比较值与索引列数据类型的一致性。 
(3) 对于复合索引,SQL语句必须使用主索引列 
(4) 索引中,尽量避免使用NULL。 
(5) 对于索引的比较,尽量避免使用NOT=(!=) 
(6) 查询列和排序列与索引列次序保持一致

6、尽量避免相同语句由于书写格式的不同,而导致多次语法分析。

7、尽量使用共享的SQL语句。

8、查询的WHERE过滤原则,应使过滤记录数最多的条件放在最前面。

9、任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。

10、in、or子句常会使用工作表,使索引失效;如果不产生大量重复值,可以考虑把子句拆开;拆开的子句中应该包含索引。

 

三、其他经验性规则

1、尽量少用嵌套查询。如必须,请用not exist代替not in子句。如例(2)

2、用多表连接代替EXISTS子句。如例(3)

3、少用DISTINCT,用EXISTS代替 如例(4)

4、使用UNION ALL、MINUS、INTERSECT提高性能

5、使用ROWID提高检索速度。对SELECT得到的单行记录,需进行DELETE、UPDATE操作时,使用ROWID将会使效率大大提高。

6、使用优化线索机制进行访问路径控制。

7、使用cursor时,显示光标优于隐式光标

 

本规范示例:

 

例一: 
SELECT aka042 -- 单位缴费划入个人帐户比例 
INTO prm_aaa043 
FROM ka01 --医疗保险单位缴费划入个人帐户比例分段信息 
WHERE akc021 = rec_kc01.akc021 -- 医疗人员类别 
AND aka041 >= rec_kc01.akc023 -- 年龄上限 
AND aka040 <= rec_kc01.akc023 -- 年龄下限 
AND aae030 <= prm_date -- 开始时间 
AND ( aae031 >= prm_date OR aae031 IS NULL ); -- 终止时间

 

例二: 
X SELECT ...... 
FROM emp 
WHERE dept_no NOT IN ( SELECT dept_no 
FROM dept 
WHERE dept_cat='A');

O SELECT ...... 
FROM emp e 
WHERE NOT EXISTS ( SELECT 'X' 
FROM dept 
WHERE dept_no=e.dept_no 
AND dept_cat='A');

 

例三: 
X SELECT ...... 
FROM emp 
WHERE EXISTS ( SELECT 'X' 
FROM dept 
WHERE dept_no=e.dept_no 
AND dept_cat='A');

O SELECT ...... 
FROM emp e,dept d 
WHERE e.dept_no=d.dept_no 
AND dept_cat='A';

 

例四: 
X SELECT DISTINCT d.dept_code,d.dept_name 
FROM dept d ,emp e 
WHERE e.dept_code=d.dept_code;

O SELECT dept_code,dept_name 
FROM dept d 
WHERE EXISTS ( SELECT 'X' 
FROM emp e 
WHERE e.dept_code=d.dept_code);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
8.用执行计划分析SQL性能      EXPLAIN PLAN是一个很好的分析SQL语句的工具,它可以在不执行SQL的情况下分析语句      通过分析,我们就可以知道ORACLE是怎样连接表,使用什么方式扫描表(索引扫描或全表扫描),以及使用到的索引名称      按照从里到外,从上到下的次序解读分析的结果      EXPLAIN PLAN的分析结果是用缩进的格式排列的,最内部的操作将最先被解读,如果两个操作处于同一层,带有最小操作号的将首先被执行      目前许多第三方的工具如PLSQL Developer和TOAD等都提供了极其方便的EXPLAIN PLAN工具      PG需要将自己添加的查询SQL文记入log,然后在EXPLAIN PLAN进行分析,尽量减少全表扫描      ORACLE SQL性能优化系列      1.选择最有效率的表名顺序(只在基于规则的优化有效)      ORACLE的解析器按照从右到左的顺序处理FROM子句的表名,因此FROM子句写在最后的表(基础表driving table)将被最先处理      在FROM子句包含多个表的情况下,必须选择记录条数最少的表作为基础表      当ORACLE处理多个表时,会运用排序及合并的方式连接它们      首先,扫描第一个表(FROM子句最后的那个表)并对记录进行排序;      然后扫描第二个表(FROM子句最后第二个表);      最后将所有从第二个表检索出的记录与第一个表合适记录进行合并      例如:      表 TAB1 16,384 条记录      表 TAB2 5 条记录      选择TAB2作为基础表 (最好的方法)      select count(*) from tab1,tab2 执行时间0.96秒      选择TAB2作为基础表 (不佳的方法)      select count(*) from tab2,tab1 执行时间26.09秒      如果有3个以上的表连接查询,那就需要选择交叉表(intersection table)作为基础表,交叉表是指那个被其他表所引用的表      例如:   EMP表描述了LOCATION表和CATEGORY表的交集   SELECT *   FROM LOCATION L,   CATEGORY C,   EMP E   WHERE E.EMP_NO BETWEEN 1000 AND 2000   AND E.CAT_NO = C.CAT_NO   AND E.LOCN = L.LOCN      将比下列SQL更有效率   SELECT *   FROM EMP E ,   LOCATION L ,   CATEGORY C   WHERE E.CAT_NO = C.CAT_NO   AND E.LOCN = L.LOCN   AND E.EMP_NO BETWEEN 1000 AND 2000      2.WHERE子句的连接顺序      ORACLE采用自下而上的顺序解析WHERE子句      根据这个原理,表之间的连接必须写在其他WHERE条件之前,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾      例如:   (低效,执行时间156.3秒)   SELECT *   FROM EMP E   WHERE SAL > 50000   AND JOB = 'MANAGER'   AND 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO);      (高效,执行时间10.6秒)   SELECT *   FROM EMP E   WHERE 25 50000   AND JOB = 'MANAGER';      3.SELECT子句避免使用'*'      当你想在SELECT子句列出所有的COLUMN时,使用动态SQL列引用'*'是一个方便的方法,不幸的是,这是一个非常低效的方法      实际上,ORACLE在解析的过程,会将'*'依次转换成所有的列名      这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间      4.减少访问数据库的次数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值