数据库优化--编码阶段

a)在语句中多写注释,注释不影响SQL语句的执行效率。增加代码的可读性。

b)尽量使事务处理达到最短,如果事务太长最好按功能将事务分开执行(如:可以让用户在界面上多几步操作)。事务太长很容易造成数据库阻塞,用户操作速度变慢或死机情况。

c)尽量减少与数据库的交互次数。如果在前端程序写有循球访问数据库操作,最好写成将数据一次读到前端再进行处理或者写成存储过程在数据库端直接处理。

只返回需要的数据

返回数据到客户端至少需要数据库提取数据、网络传输数据、客户端接收数据以及客户端处理数据等环节,如果返回不需要的数据,就会增加服务器、网络和客户端的无效劳动,其害处是显而易见的,避免这类事件需要注意:

1.不要写SELECT *的语句,而是选择你需要的字段。数据分页处理

2.合理写WHERE子句,不要写没有WHERE的SQL语句。用Where子句替换HAVING子句

3.没有必要时不要用DISTINCT和ORDER BY, 这些动作可以改在客户端执行,它们增加了额外的开销。用EXISTS替换DISTINCT
(低效):
select distinct deptno,dname from dept d , emp e where d.deptno=e.deptno
(高效):
select distinct deptno,dname from dept d , where exists ( select ‘x’ from emp ewhere d.deptno=e.deptno);

4.用IN来替换OR
低效:
Select * from emp where job=’CLERK’ or job = ‘MANAGER’ or job=’SALESMAN’;
高效
Select * from emp where job in (’CLERK’,‘MANAGER’,’SALESMAN’);

5.Between能够更快地根据索引找到范围。
select * from emp where deptno in (10,20)
Select * from emp where between 10 and 20 是一样的。由于in会在比较多次,所以有时会慢些。

6.注意union和 union all 的区别 , UNION all执行效率高。

7.如果一次性插入数据量很大,那么可以使用select into代替create table,避免log,提高速度;如果数据量不大,为了缓和系统表的资源,建议先create table,然后insert。
注意SELECT INTO后的WHERE子句,因为SELECT INTO把数据插入到临时表,这个过程会锁定一些系统表,如果这个WHERE子句返回的数据过多或者速度太慢,会造成系统表长期锁定,诸塞其他进程。

8.用>=替代>
高效:
Select * from emp where deptno >=4;
低效:
Select * from emp where deptno >3;
两者的区别在于, 前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录。

9.对于聚合查询,可以用HAVING子句进一步限定返回的行。
select deptno,count(1) from emp group by deptno having count(1)>1;
select count(*) from table;这样不带任何条件的count会引起全表扫描,并且没有任何业务意义,是一定要杜绝的。
count函数只有在统计表中所有行数时使用,而且count(1)比count(*)更有效率。

优化GROUP BY:
提高GROUP BY 语句的效率, 可以通过将不需要的记录在GROUP BY 之前过滤掉.下面两个查询返回相同结果但第二个明显就快了许多.
低效:
Select job,avg(sal) from emp group by job having job = ‘PRESIDENT’ or job = ‘MANAGER’;
高效:
Select job,avg(sal) from emp where job = ‘PRESIDENT’ or job = ‘MANAGER’ group by job;

尽量少做重复的工作

A、控制同一语句的多次执行,特别是一些基础数据的多次执行是很多程序员很少注意的。

B、减少多次的数据转换,也许需要数据转换是设计的问题,但是减少次数是程序员可以做到的。

C、杜绝不必要的子查询和连接表,子查询在执行计划一般解释成外连接,多余的连接表带来额外的开销。

D、合并对同一表同一条件的多次UPDATE,比如
update emp set sal=6000 where ename = ‘SMITH’
  update emp set comm=6000 where ename = ‘SMITH’

这两个语句应该合并成以下一个语句
update emp set sal=6000,comm=6000 where ename = ‘SMITH’

E、 UPDATE操作不要拆成DELETE操作+INSERT操作的形式,虽然功能相同,但是性能差别是很大的。

F、不要写一些没有意义的查询,比如
select * from emp where 1 = 1;

SQL书写的影响

同一功能同一性能不同写法SQL的影响。

如一个SQL在
A程序员写的为 select * from zl_yhjbqk
B程序员写的为 select * from dlyx.zl_yhjbqk(带表所有者的前缀)
C程序员写的为 select * from DLYX.ZLYHJBQK(大写表名)
D程序员写的为 select * from DLYX.ZLYHJBQK(中间多了空格)

以上四个SQL在ORACLE分析整理之后产生的结果及执行的时间是一样的,但是从ORACLE共享内存SGA的原理,可以得出ORACLE对每个SQL 都会对其进行一次分析,并且占用共享内存,如果将SQL的字符串及格式写得完全相同,则ORACLE只会分析一次,共享内存也只会留下一次的分析结果,这不仅可以减少分析SQL的时间,而且可以减少共享内存重复的信息,ORACLE也可以准确统计SQL的执行频率。sql语句用大写的;因为oracle总是先解析sql语句,把小写的字母转换成大写的再执行。

WHERE后面的条件顺序影响

WHERE子句后面的条件顺序对大数据量表的查询会产生直接的影响。如:
Select * from emp where sal > 2000 and job=’MANAGER’;
Select * from emp where job=’MANAGER’ and sal > 2000;
以上两个SQL中sal 及job两个字段都没进行索引,所以执行的时候都是全表扫描,第二条SQL的CPU占用率比第一条低。

注意连接条件的写法

多表连接的连接条件对索引的选择有着重要的意义,所以我们在写连接条件条件的时候需要特别的注意。

A、多表连接的时候,连接条件必须写全,宁可重复,不要缺漏。

B、连接条件尽量使用聚集索引

C、 注意ON部分条件和WHERE部分条件的区别

其他需要注意的地方

  经验表明,问题发现的越早解决的成本越低,很多性能问题可以在编码阶段就发现,为了提早发现性能问题,需要注意:
  A、程序员注意、关心各表的数据量。
  B、 编码过程和单元测试过程尽量用数据量较大的数据库测试,最好能用实际数据测试。
  C、每个SQL语句尽量简单
  D、不要频繁更新有触发器的表的数据
  E、注意数据库函数的限制以及其性能
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值