数据库性能优化总结

        数据库性能优化四个原则:

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

        一、建立并正确使用索引

         SQL什么条件会使用索引?
        当字段上建有索引时,一般如下状况会使用索引:
        INDEX_COLUMN = 、> 、>= 、< 、<= 、?between ? and ?、in (?,?,...,?)、like ?||'%'(后导模糊查询)
        T1. INDEX_COLUMN=T2. COLUMN1(两个表经过索引字段关联)
        SQL什么条件不会使用索引?
        <>  not in (?,?,...,?)
        function(INDEX_COLUMN) = ?
        INDEX_COLUMN + 1 = ?
        INDEX_COLUMN || 'a' = ?
        通过普通运算或函数运算后的索引字段不能使用索引
        INDEX_COLUMN like '%'||?
        INDEX_COLUMN like '%'||?||'%'
        含前导模糊查询的Like语法不能使用索引
        INDEX_COLUMN is null
        B-TREE索引里不保存字段为NULL值记录,所以IS NULL不能使用索引
        NUMBER_INDEX_COLUMN='12345'
        CHAR_INDEX_COLUMN=12345
        Oracle在作数值比较时须要将两边的数据转换成同一种数据类型,若是两边数据类型不一样时会对字段值隐式转换,至关于加了一层函数处理,因此不能使用索引。
        a.INDEX_COLUMN=a.COLUMN_1
        给索引查询的值应是已知数据,不能是未知字段值。
        注:通过函数运算字段的字段要使用可使用函数索引,这种需求建议与DBA沟通。
有时候咱们会使用多个字段的组合索引,若是查询条件中第一个字段不能使用索引,那整个查询也不能使用索引
 
        咱们通常在什么字段上建索引?
        这是一个很是复杂的话题,须要对业务及数据充分分析后再能得出结果。主键及外键一般都要有索引,其它须要建索引的字段应知足如下条件:
    一、字段出如今查询条件中,而且查询条件可使用索引;
    二、语句执行频率高,一天会有几千次以上;
 
    如下是一些字段是否须要建的经验分类:
         须要建索引的字段
        主键、外键、有标识意义字段
数据库

        长字符不适合建索引的字段、描述备注、大字段 
        如何知道SQL是否使用了正确的索引?
        简单SQL能够根据索引使用语法规则判断,复杂的SQL很差办,判断SQL的响应时间是一种策略,可是这会受到数据量、主机负载及缓存等因素的影响,有时数据全在缓存里,可能全表访问的时间比索引访问时间还少。要准确知道索引是否正确使用,须要到数据库中查看SQL真实的执行计划,这个话题比较复杂,详见SQL执行计划专题介绍。
 
        索引对DML(INSERT,UPDATE,DELETE)附加的开销有多少?这个没有固定的比例,与每一个表记录的大小及索引字段大小密切相关,如下是一个普通表测试数据,仅供参考:
        索引对于Insert性能下降56%
        索引对于Update性能下降47%
        索引对于Delete性能下降29%
        所以对于写IO压力比较大的系统,表的索引须要仔细评估必要性,另外索引也会占用必定的存储空间。
浏览器

        二、只经过索引访问

        有些时候,咱们只是访问表中的几个字段,而且字段内容较少,咱们能够为这几个字段单独创建一个组合索引,这样就能够直接只经过访问索引就能获得数据,通常索引占用的磁盘空间比表小不少,因此这种方式能够大大减小磁盘IO开销。如:select id,name from company where type='2';若是这个SQL常用,咱们能够在type,id,name上建立组合索引create index my_comb_index on company(type,id,name);有了这个组合索引后,SQL就能够直接经过my_comb_index索引返回数据,不须要访问company表。
        仍是拿字典举例:有一个需求,须要查询一本汉语字典中全部汉字的个数,若是咱们的字典没有目录索引,那咱们只能从字典内容里一个一个字计数,最后返回结果。若是咱们有一个拼音目录,那就能够只访问拼音目录的汉字进行计数。若是一本字典有1000页,拼音目录有20页,那咱们的数据访问成本至关于全表访问的50分之一。
        切记,性能优化是无止境的,当性能能够知足需求时便可,不要过分优化。在实际数据库中咱们不可能把每一个SQL请求的字段都建在索引里,因此这种只经过索引访问数据的方法通常只用于核心应用,也就是那种对核心表访问量最高且查询字段数据量不多的查询。
缓存

        2、减小数据返回(减小网络传输和磁盘访问)

        一、对数据分页处理
        客户端(应用程序或浏览器)分页


        将数据从应用服务器所有下载到本地应用程序或浏览器,在应用程序或浏览器内部经过本地代码进行分页处理
        优势:编码简单,减小客户端与应用服务器网络交互次数
        缺点:首次交互时间长,占用客户端内存
        适应场景:客户端与应用服务器网络延时较大,但要求后续操做流畅,如手机GPRS,超远程访问(跨国)等等。
性能优化

        应用服务器分页


        将数据从数据库服务器所有下载到应用服务器,在应用服务器内部再进行数据筛选。如下是一个应用服务器端Java程序分页的示例:List list=executeQuery(“select * from employee order by id”);服务器

        Int count= list.size();List subList= list.subList(10, 20);
 
        优势:编码简单,只须要一次SQL交互,总数据与分页数据差很少时性能较好。
        缺点:总数据量较多时性能较差。
        适应场景:数据库系统不支持分页处理,数据量较小而且可控。
网络

 
        数据库SQL分页


        采用数据库SQL分页须要两次SQL完成
        一个SQL计算总数量
        一个SQL返回分页后的数据
        优势:性能好
        缺点:编码复杂,各类数据库语法不一样,须要两次SQL交互。
框架

        二、只返回须要的数据、避免使用select *

        3、减小交互次数(减小网络传输)

        一、 batch  DML

        数据库访问框架通常都提供了批量提交的接口,jdbc支持batch的提交处理方法,当你一次性要往一个表中插入1000万条数据时,若是采用普通的executeUpdate处理,那么和服务器交互次数为1000万次,按每秒钟能够向数据库服务器提交10000次估算,要完成全部工做须要1000秒。若是采用批量提交模式,1000条提交一次,那么和服务器交互次数为1万次,交互次数大大减小。采用batch操做通常不会减小不少数据库服务器的物理IO,可是会大大减小客户端与服务端的交互次数,从而减小了屡次发起的网络延时开销,同时也会下降数据库的CPU开销。函数

        二、in list

        对于一次查询多个id的状况尽可能用in,而不是循环屡次去数据库查询。能够减小与数据库交互。性能

        三、设置fetch size

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

        四、使用存储过程

        存储过程能够提升性能,可是一样存在缺点,不可移植性,学习成本高,业务逻辑多处存在不方便后期维护。 普通业务逻辑尽可能不要使用存储过程,定时性的ETL任务或报表统计函数能够根据团队资源状况采用存储过程处理。

        五、优化业务逻辑,少链接数据库

        连表操做操做时尽可能数量少的表做为主表,

        4、减小服务器及cpu开销

        一、使用绑定变量

         绑定变量是指SQL中对变化的值采用变量参数的形式提交,而不是在SQL中直接拼写对应的值。
        非绑定变量写法:Select * from employee where id=1234567
        绑定变量写法:
        Select * from employee where id=? Preparestatement.setInt(1,1234567)
 
        Java中Preparestatement就是为处理绑定变量提供的对像,绑定变量有如下优势:
        一、防止SQL注入
        二、提升SQL可读性
        三、提升SQL解析性能,不使用绑定变动咱们通常称为硬解析,使用绑定变量咱们称为软解析。

        二、减小比较操做

            尽可能少使用like ‘%abc%

相关文章
相关标签/搜索