银行 数据库

使用optimize for解决分页问题

大数据量的分页问题经常会困扰我们。
这里分享一个简单实用的方法:

假设某个表 T 拥有 200万记录。
一般分页的SQL会是这样:

select *  from
( select * ,row_number() over ( order by C1 ) as rn
  from T ) a
where rn >= start_row and rn <= end_row

一般这个会比较慢,因为T表很大,全表排序效率很低,
而且每查一次都会做一次,数据库压力太大。

其实仔细想一下,一般来讲用户不需要这么多页。
如果一页20条记录,则会有10万页的结果,根本看不完。
用户一般都会只关注前面几十页。

所以我们可以加上fetch first rows only 来限制一下结果集。

SQL改写如下:

select *  from
( select * ,row_number() over ( order by C1 ) as rn
  from T fetch fist 20000 rows only) a
where rn >= start_row and rn <= end_row
(20000 只是一个举例,可以按需求调整)

但是仅仅这样还不行,全表排序免不了。
所以我们想到了索引,
Create index idx1 on T (C1)
让DB2用索引排序代替全表排序。

这样就行了吗?答案是可能还不行。
因为你是select * ,所以DB2认为走索引还不如全表排序。
尤其你的索引 cluster 不是太好的时候。

其实我们的目的是尽快出前 20000 条,其他的我们不管。
所以这时我们可以用 optimize for N rows语句,告诉DB2
你只要尽快把 20000 条出给我就行了,我不关心全表排序要多长时间。
这时 DB2 就会选择索引扫描来排序了。。。
SQL改写如下:
select *
( select * ,row_number() over ( order by C1 ) as rn
  from T  fetch first 20000 rows only) a
where rn >= start_row and rn <= end_row
optimize for 20000 rows

在真实的案例中,这句optimize for N rows将
查询从40秒调高到了3秒。
参与7

6 同行回答

dongxincun dongxincun 软件开发工程师 YTEC
很好的例子,我们项目也遇到过类似的分页查询性能问题,另外前端应用如果是用hibernate,还能避免翻页的时候再提交SQL到后台数据库执行,而是直接从LIST缓存中直接取第2页的数据。显示全部
很好的例子,我们项目也遇到过类似的分页查询性能问题,另外前端应用如果是用hibernate,还能避免翻页的时候再提交SQL到后台数据库执行,而是直接从LIST缓存中直接取第2页的数据。 收起
互联网服务 · 2012-05-08
浏览1319
ppjava2009 ppjava2009 系统工程师 用友汽车信息科技(上海)有限公司
我觉得2#有道理,where不是可以过滤数据吗,而且C1有索引,over部分就会有索引排序,、显示全部
我觉得2#有道理,where不是可以过滤数据吗,而且C1有索引,over部分就会有索引排序,、 收起
互联网服务 · 2012-03-06
浏览1321
棉花糖ONE 棉花糖ONE 数据库管理员 用友软件
不错 :)显示全部
不错 :) 收起
互联网服务 · 2011-12-28
浏览1316
galzero galzero 数据库管理员 交通银行太平洋信用卡中心
select *( select * ,row_number() over ( order by C1 ) as rn  from T ) awhere rn >= start_row and rn 显示全部
select *
( select * ,row_number() over ( order by C1 ) as rn
  from T ) a
where rn >= start_row and rn <= end_row
fetch first 20000 rows only optimize for 20000 rows
我感觉是不是这样写更明确一点? 收起
金融其它 · 2011-12-27
浏览1314
galzero galzero 数据库管理员 交通银行太平洋信用卡中心
恩 精彩啊显示全部
恩 精彩啊 收起
金融其它 · 2011-12-27
浏览1333
xxzmxx xxzmxx 软件开发工程师 招行软件中心
理论上优化器会运用where后面的谓词条件过滤数据啊显示全部
理论上优化器会运用where后面的谓词条件过滤数据啊 收起
互联网服务 · 2011-12-25
浏览1333

提问者

mdkii
软件开发工程师 bocn
擅长领域: 数据库存储服务器
评论694

相关问题

相关资料

相关文章

问题状态

  • 发布时间:2011-12-23
  • 关注会员:1 人
  • 问题浏览:17296
  • 最近回答:2012-05-08
  • X社区推广