2、返回更少的数据
2.1、数据分页处理
一般数据分页方式有:
2.1.1、客户端(应用程序或浏览器)分页
将数据从应用服务器全部下载到本地应用程序或浏览器,在应用程序或浏览器内部通过本地代码进行分页处理
优点:编码简单,减少客户端与应用服务器网络交互次数
缺点:首次交互时间长,占用客户端内存
适应场景:客户端与应用服务器网络延时较大,但要求后续操作流畅,如手机GPRS,超远程访问(跨国)等等。
2.1.2、应用服务器分页
将数据从数据库服务器全部下载到应用服务器,在应用服务器内部再进行数据筛选。以下是一个应用服务器端Java程序分页的示例:
List list=executeQuery(“select * from employee order by id”); Int count= list.size(); List subList= list.subList(10, 20); |
优点:编码简单,只需要一次SQL交互,总数据与分页数据差不多时性能较好。
缺点:总数据量较多时性能较差。
适应场景:数据库系统不支持分页处理,数据量较小并且可控。
2.1.3、数据库SQL分页
采用数据库SQL分页需要两次SQL完成
一个SQL计算总数量
一个SQL返回分页后的数据
优点:性能好
缺点:编码复杂,各种数据库语法不同,需要两次SQL交互。
oracle数据库一般采用rownum来进行分页,常用分页语法有如下两种:
直接通过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
采用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);