数据库 开发规范
1.下面是最高效的删除重复记录方法示例
DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) FROM EMP X WHERE X.EMP_NO = E.EMP_NO );
(因为使用了 ROWID)
2.多表关联方式
1.HASH JOIN
当需要进行多表关联操作时,选择使用全表扫描的方式在其中一个表的关联字段上创建 HASH 表(该表一般选择较小的表,以便可以存于 SGA 内存中,并达到提高探测的速度的 目的),然后对另一表上进行全表扫描且以同样的算法构建 HASH 表,同时探测基于第一 个表中上 HASH 表,查找匹配的键值
使用场景:大数据量等值关联查询,如关联查询大量用户资料及其清单数据。
等值联接
2.NESTED LOOP JOIN
优化器选择一个驱动表 A 作为循环扫描的外部表。
另外一个相关联的表 B 作为内部表。
每扫描驱动表 A 中一条记录,ORACLE 扫描 B 表中所有满足关联条件的记录。
3.SORT MERGE JOIN
当需要进行多表关联操作时,对相关联的表按关联字段进行排序,然后从各已排序好的 结果中取得关联结果。
适用于非等值关联、数据量比较大的场合。
在对大数据量的关联查询,且条件为非等值条件,此时性能要好于 nested loop join。
在大多数情况下,HASH JOIN 方式比该种关联方式高效。
3.书写规范
0. nEventId SUBS_EVENT.EVENT_ID%type
nEventId参数的数据度类型跟SUBS_EVENT表的EVENT_ID字段类型一样,这样,你修改这个表的EVENT_ID字段类型,就不用改存储权过程了。
1.SQL 语句的所有表名、字段名全部大写,系统保留字、内置函数名、SQL 保留字也大写
2.使用 INSERT 时,必须指定插入的字段名,严禁不指定字段名直接插入 VALUES
3.=、=、<>等符号前后加上一个空格
4..逗号之后必须接一个空格或换行
5.关键字、保留字和左括号之间必须有一个空格或换行
6.最外层的 CREATE、BEGIN、END 等关键字要顶格书写
7.对于存储过程、Function、视图等数据库对象,缩进为 4 个空格,禁止使用 TAB 符号
8.一行有多列,超过 120 个字符时,基于列对齐原则,采用下行向右缩进;
WHERE 子句书写时,每个条件占一行,语句另起一行时,以保留字开始,保留字右对齐, 对于连接符=、=之类的不换行 ;
同一语句中的 SELECT、UPDATE、SET、INSERT、DELETE、FROM、WHERE、ORDER BY、GROUP BY、HAVING 等第一个关键字换行后右对齐;如果有关键字长度大于 SELECT/DELETE/UPDATE,则采用左对齐;
9. IF THEN ELSE、FOR LOOP、WHILE、UNTIL 等嵌套语句的子句部分增加一个向右缩进
10.多表.连接时,使用表的别名来引用列,一个表及其别名一行,折行后表名与上一行表名对 齐
11.尽量减少数据库负担
12.避免大表关联,大表关联可能存在性能问题
13.禁止 SQL 语句直接拼接参数,而不使用绑定变量
14.禁止使用“SELECT *”这样的语句,特别是在程序代码内部
15.尽量避免多表的关联操作
16.尽量使用 UNION ALL 代替 UNION
17.禁止 SQL 内层使用 ORDER BY 和 GROUP BY 排序操作
18.尽量减少外层使用 ORDER BY 和 GROUP BY 排序操作
19.不允许对索引列进行计算
20.注意比较值与索引列数据类型的一致性,避免使用数据库的类型自动转换功能
21.对于复合索引,SQL 语句的 WHERE 查询条件总是使用索引的第一列
22.使用 Oracle 的函数索引解决空字段导致索引失效的问题
Note:索引 IDX_PPS_PWD ON SUBS(PPS_PWD,0),走索引
23.对于索引的比较,尽量避免使用不等于(!=)
24.在 IF/ELSE 类型的查询中,可使用 DECODE 替代
25.用 CASE … WHEN … THEN … ELSE … END 格式减少表的扫描次数
26.用 WHERE 子句替换 HAVING 子句
27.LIKE 子句尽量前端匹配
28.程序代码中禁止使用 DB_LINK,其他场景下尽量不使用 DB_LINK
29 避免超长 SQL,SQL 长度不可超过 4000 长度
30.SQL 子查询嵌套不宜超过 3 层
31.避免不必要的排序
32.查询分页场景,建议如下分页格式,先查询过滤出一部分数据,再做下一层过滤查询
33.尽量避免 HINT 在代码中出现,并行度使用需谨慎
34.SQL 里面避免使用标量子查询,标量子查询全部使用外连接实现
35.不要将空的变量值直接与比较运算符比较
IF vUserName IS NULL
THEN vUserName = ‘UNKOWN’;
END IF;
36.多表关联和复杂的 SQL,需要进行执行计划分析
37.清空表记录用 TRUNCATE 替代 DELETE
36.用 EXISTS 替换 DISTINCT
38.用 UNION 替换 OR(适用于索引列)
39.如果检索数据量超过 30%的表中记录数,使用索引将没有显著的效率提高。在
40.尽量减少 SQL 复杂度