程序员数据库访问的优化的一些思考

1、数据库访问优化的五个法则程序员

    在实际开发,咱们主要是须要对SQL语句进行优化,咱们须要快速定位能性的瓶颈点,也就是说快速找到咱们SQL主要的开销在哪里?根据木桶原理能够知道,最慢的设备每每是性能瓶颈。例如:互联网运用中的带宽,本地数据复制时的硬盘的访问速度。
算法

    根据当前计算机硬件的基本性能指标及其在数据库中主要操做内容,能够整理出以下五条性能基本优化法则:sql

      (1)减小数据访问(减小磁盘访问)数据库

     (2)返回更少数据(减小网络传输或磁盘访问)浏览器

   (3)减小交互次数(减小网络传输)性能优化

   (4)减小服务器CPU开销(减小CPU及内存开销)服务器

   (5) 利用更多资源(增长资源)网络

因为每一层优化法则都是解决其对应硬件的性能问题,因此带来的性能提高比例也不同。传统数据库系统设计是也是尽量对低速设备提供优化方法,所以针对低速设备问题的可优化手段也更多,优化成本也更低。咱们任何一个SQL的性能优化都应该按这个规则由上到下来诊断问题并提出解决方案,而不该该首先想到的是增长资源解决问题。并发

如下是每一个优化法则层级对应优化效果及成本经验参考:oracle

优化法则

性能提高效果

优化成本

减小数据访问

1~1000

返回更少数据

1~100

减小交互次数

1~20

减小服务器CPU开销

1~5

利用更多资源

@~10

2、数据库访问优化法则详解

2.一、减小数据访问

(1)正确建立索引

索引有哪些种类?

常见的索引有B-TREE索引、位图索引、全文索引,位图索引通常用于数据仓库应用,全文索引因为使用较少,这里不深刻介绍。B-TREE索引包括不少扩展类型,如组合索引、反向索引、函数索引等等,如下是B-TREE索引的简单介绍:

B-TREE索引也称为平衡树索引(Balance Tree),它是一种按字段排好序的树形目录结构,主要用于提高查询性能和惟一约束支持。B-TREE索引的内容包括根节点、分支节点、叶子节点。

咱们通常在什么字段上建索引?

这是一个很是复杂的话题,须要对业务及数据充分分析后再能得出结果。主键及外键一般都要有索引,其它须要建索引的字段应知足如下条件:

        1、字段出如今查询条件中,而且查询条件可使用索引;

        2、语句执行频率高,一天会有几千次以上;

        3、经过字段条件可筛选的记录集很小,那数据筛选比例是多少才适合?

这个没有固定值,须要根据表数据量来评估,如下是经验公式,可用于快速评估:

小表(记录数小于10000行的表):筛选比例<10%

大表:(筛选返回记录数)<(表总记录数*单条记录长度)/10000/16

 单条记录长度≈字段平均内容长度之和+字段数*2

索引对DML(INSERT,UPDATE,DELETE)附加的开销有多少?

 这个没有固定的比例,与每一个表记录的大小及索引字段大小密切相关,如下是一个普通表测试数据,仅供参考:

索引对于Insert性能下降56%

索引对于Update性能下降47%

索引对于Delete性能下降29%

所以对于写IO压力比较大的系统,表的索引须要仔细评估必要性,另外索引也会占用必定的存储空间。

(2)只经过索引访问数据

有些时候,咱们只是访问表中的几个字段,而且字段内容较少,咱们能够为这几个字段单独创建一个组合索引,这样就能够直接只经过访问索引就能获得数据,通常索引占用的磁盘空间比表小不少,因此这种方式能够大大减小磁盘IO开销。

(3)优化SQL执行计划

SQL执行计划是关系型数据库最核心的技术之一,它表示SQL执行时的数据访问算法。因为业务需求愈来愈复杂,表数据量也愈来愈大,程序员愈来愈懒惰,SQL也须要支持很是复杂的业务逻辑,但SQL的性能还须要提升,所以,优秀的关系型数据库除了须要支持复杂的SQL语法及更多函数外,还须要有一套优秀的算法库来提升SQL性能。

2.二、返回更少的数据

减小数据的返回也是优化的重要手段,主要有两种方法 分页 和 只返回须要的字段。

(1)分页

分页总共包括三种分页方式:客户端分页、服务端分页、数据库分页。

客服端分页将数据从应用服务器所有下载到本地应用程序或浏览器,在应用程序或浏览器内部经过本地代码进行分页处理。

优势:编码简单,减小客户端与应用服务器网络交互次数

缺点:首次交互时间长,占用客户端内存

适应场景:客户端与应用服务器网络延时较大,但要求后续操做流畅,如手机GPRS,超远程访问(跨国)等等。

服务端分页:将数据从数据库服务器所有下载到应用服务器,在应用服务器内部再进行数据筛选。

优势:编码简单,只须要一次SQL交互,总数据与分页数据差很少时性能较好。

缺点:总数据量较多时性能较差。

适应场景:数据库系统不支持分页处理,数据量较小而且可控。

数据库分页:采用数据库SQL分页须要两次SQL完成,一个SQL计算总数量,一个SQL返回分页后的数据。

优势:性能好

缺点:编码复杂,各类数据库语法不一样,须要两次SQL交互。

ps:oracle数据库通常采用rownum来进行分页。经常使用分页方式以下

rownum分页:

select * from (
         select a.*,rownum rn from
                   (select * from student a where id=? order by status) a
         where rownum<=20)
where rn>10;

rowid分页语法:

select b.* from (
         select * from (
                   select a.*,rownum rn from
                            (select rowid rid,status from student a where id=? order by status) a
                   where rownum<=20)
         where rn>10) a, student b
where a.rid=b.rowid;

(2)只返回须要的字段

经过去除没必要要的返回字段能够提升性能。

优势:

1、减小数据在网络上传输开销

2、减小服务器数据处理开销

3、减小客户端内存占用

4、字段变动时提早发现问题,减小程序BUG

5、若是访问的全部字段恰好在一个索引里面,则可使用纯索引访问提升性能。

缺点:增长编码工做量

2.三、减小交互的次数

(1) batch 操做

数据库访问框架通常都提供了批量提交的接口,jdbc支持batch的提交处理方法,咱们能够批量插入、更新和删除数据。这样交互次数大大减小。采用batch操做通常不会减小不少数据库服务器的物理IO,可是会大大减小客户端与服务端的交互次数,从而减小了屡次发起的网络延时开销,同时也会下降数据库的CPU开销。

(2)in

不少时候咱们须要按一些ID查询数据库记录,咱们能够采用一个ID一个请求发给数据库,以下所示:

for :var in ids[] do begin
  select * from mytable where id=:var;
end;

咱们也能够作一个小的优化, 以下所示,用ID INLIST的这种方式写SQL

select * from mytable where id in(:id1,id2,...,idn);

经过这样处理能够大大减小SQL请求的数量,从而提升性能。那若是有10000ID,那是否是所有放在一条SQL里处理呢?答案确定是否认的。首先大部份数据库都会有SQL长度和IN里个数的限制,如ORACLEIN里就不容许超过1000个值

另外当前数据库通常都是采用基于成本的优化规则,当IN数量达到必定值时有可能改变SQL执行计划,从索引访问变成全表访问,这将使性能急剧变化。随着SQLIN的里面的值个数增长,SQL的执行计划会更复杂,占用的内存将会变大,这将会增长服务器CPU及内存成本。

评估在IN里面一次放多少个值还须要考虑应用服务器本地内存的开销,有并发访问时要计算本地数据使用周期内的并发上限,不然可能会致使内存溢出。

综合考虑,通常IN里面的值个数超过20个之后性能基本没什么太大变化,也特别说明不要超过100,超事后可能会引发执行计划的不稳定性及增长数据库CPU及内存成本.

(3)设置Fetch Size

    当咱们采用select从数据库查询数据时,数据默认并非一条一条返回给客户端的,也不是一次所有返回客户端的,而是根据客户端fetch_size参数处理,每次只返回fetch_size条记录,当客户端游标遍历到尾部时再从服务端取数据,直到最后所有传送完成。因此若是咱们要从服务端一次取大量数据时,能够加大fetch_size,这样能够减小结果数据传输的交互次数及服务器数据准备时间,提升性能。

2.四、减小数据库服务器CPU运算

(1) 使用绑定变量

JavaPreparestatement就是为处理绑定变量提供的对像,绑定变量有如下优势:

1、防止SQL注入

2、提升SQL可读性

3、提升SQL解析性能,不使用绑定变动咱们通常称为硬解析,使用绑定变量咱们称为软解析。

(2)合理使用排序

(3)减小比较操做

(4)大量复杂运算在客户端处理

2.五、利用更多的资源

(1)客户端多进程并行访问

    多进程并行访问是指在客户端建立多个进程(线程),每一个进程创建一个与数据库的链接,而后同时向数据库提交访问请求。当数据库主机资源有空闲时,咱们能够采用客户端多进程并行访问的方法来提升性能。若是数据库主机已经很忙时,采用多进程并行访问性能不会提升,反而可能会更慢。因此使用这种方式最好与DBA或系统管理员进行沟通后再决定是否采用。

(2)数据库并行处理

相关文章
相关标签/搜索