zoukankan      html  css  js  c++  java
  • 数据库访问优化之二:返回更少的数据

    1、数据分页处理

    一般数据分页方式有:

    1.1、客户端(应用程序或浏览器)分页

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

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

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

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

    1.2、应用服务器分页

    将数据从数据库服务器全部下载到应用服务器,在应用服务器内部再进行数据筛选。以下是一个应用服务器端Java程序分页的示例:

    List list=executeQuery(“select * from employee order by id”);
    Int count= list.size();
    List subList= list.subList(10, 20);

    优点:编码简单,只需要一次SQL交互,总数据与分页数据差不多时性能较好。

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

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

    1.3、数据库SQL分页

    采用数据库SQL分页需要两次SQL完成,

    一个SQL计算总数量,一个SQL返回分页后的数据

    优点:性能好

    缺点:编码复杂,各种数据库语法不同,需要两次SQL交互。

    oracle数据库一般采用rownum来进行分页,常用分页语法有如下两种:

    1. 直接通过rownum分页:

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

    数据访问开销=索引IO+索引全部记录结果对应的表数据IO。

     2. 采用rowid分页语法

    优化原理是通过纯索引找出分页记录的ROWID,再通过ROWID回表返回数据,要求内层查询和排序字段全在索引里。

    create index myindex on product(company_id,status);
    
    select b.* from (
             select * from (
                       select a.*,rownum rn from
                                (select rowid rid,status from product a where company_id=? order by status) a
                       where rownum<=20)
             where rn>10) a, product b
    where a.rid=b.rowid;

    数据访问开销=索引IO+索引分页结果对应的表数据IO

    实例:

    一个公司产品有1000条记录,要分页取其中20个产品,假设访问公司索引需要50个IO,2条记录需要1个表数据IO。

    那么按第一种ROWNUM分页写法,需要550(50+1000/2)个IO,按第二种ROWID分页写法,只需要60个IO(50+20/2);

    2、只返回需要的字段

    通过去除不必要的返回字段可以提高性能,例:

    调整前:select * from product where company_id=?;

    调整后:select id,name from product where company_id=?;

    优点:

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

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

    3、减少客户端内存占用

    4、字段变更时提前发现问题,减少程序BUG

    5、如果访问的所有字段刚好在一个索引里面,则可以使用纯索引访问提高性能。

    缺点:增加编码工作量

    由于会增加一些编码工作量,所以一般需求通过开发规范来要求程序员这么做,否则等项目上线后再整改工作量更大。

    如果你的查询表中有大字段或内容较多的字段,如备注信息、文件内容等等,那在查询表时一定要注意这方面的问题,否则可能会带来严重的性能问题

    如果表经常要查询并且请求大内容字段的概率很低,我们可以采用分表处理,将一个大表分拆成两个一对一的关系表,将不常用的大内容字段放在一张单独的表中。

    如一张存储上传文件的表:

    T_FILE(ID,FILE_NAME,FILE_SIZE,FILE_TYPE,FILE_CONTENT)

    我们可以分拆成两张一对一的关系表:

    T_FILE(ID,FILE_NAME,FILE_SIZE,FILE_TYPE)

    T_FILECONTENT(ID, FILE_CONTENT)

             通过这种分拆,可以大大提少T_FILE表的单条记录及总大小,这样在查询T_FILE时性能会更好,当需要查询FILE_CONTENT字段内容时再访问T_FILECONTENT表。

  • 相关阅读:
    SQLServer存储过程实现单条件分页
    AJAX遮罩实例
    JS获取网站StatusCode,若存在写入文件
    AJAX同步和异步的区别
    通过JS将BSAE64生成图片并下载
    Bootstrap学习-排版-表单
    Bootstrap学习-环境安装
    这才是你需要的最基础的.Net基础面试题(通俗易懂,最基础的.Net)
    这才是你需要的最基础的.Net基础面试题(通俗易懂,最基础的.Net)
    这才是你需要的最基础的.Net基础面试题(通俗易懂,最基础的.Net)
  • 原文地址:https://www.cnblogs.com/peterYong/p/11410489.html
Copyright © 2011-2022 走看看