我也来凑个热闹,Oracle下500万记录分页(含思路)

tongzhenhua 2004-06-30 11:12:25
http://211.155.226.126:8090/UploadFile/500W分页录像.rar

没办法。我没网站。只好做个录像了。:)录像时占了不少资源。实际还要快一点。

原理可见《Hibernate分页查询原理解读》,也是泊来品。谁写的我忘记了。google一下吧。

public String getLimitString(String sql) {
StringBuffer pagingSelect = new StringBuffer(100);
pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
pagingSelect.append(sql);
pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
return pagingSelect.toString();
}

Oracle采用嵌套3层的查询语句结合rownum来实现分页,这在Oracle上是最快的方式,如果只是一层或者两层的查询语句的rownum不能支持order by。

也就是根据这个写的。
实际代码

private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
TzhPager1.SelectCommand="select id,age,sex,memo from test";
TzhPager1.ConnectionString="user id=test500;password=test500;data source=db01";
TzhPager1.CurrentPageIndex = 0;
TzhPager1.DataBind();
}
}

就是扔一个任意合法的sql,生成一个新的SQL,再执行。没用存储过程。数据库里的表连索引都没建。:)
...全文
470 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
leavesbywind 2004-07-03
  • 打赏
  • 举报
回复
up
billy_zh 2004-07-02
  • 打赏
  • 举报
回复
没什么好介意的啦!
我更关注于适用性,所以必须有取舍。
billy_zh 2004-07-02
  • 打赏
  • 举报
回复
to cnlamar(无中生有)

遍历一个select id form table的数据

和遍历一个select * from table的数据速度上是有很大差别的,特别是字段多的时候,

你用事件探查器看一个就知道了。

-------------
我说的这个方法并不适用于数据非常多的情况下,但是20w数据我测试过,
最后一页也不会超过1s(当然还要看服务器的负载)
cnlamar 2004-07-02
  • 打赏
  • 举报
回复
billy_zh:,我说话向来都有点直,但我心里没什么,请不要介意~~`
billy_zh 2004-07-02
  • 打赏
  • 举报
回复
我无话好说了. 再不UP了.
cnlamar 2004-07-02
  • 打赏
  • 举报
回复

zooo(用zipp火机,抽骆驼烟):我懒,就写过这一个而已。。。

http://blog.csdn.net/cnlamar/archive/2004/06/30/30641.aspx?Pending=true
wang790809 2004-07-02
  • 打赏
  • 举报
回复
分页时记录的总数怎么处理
greatjoshuama 2004-07-02
  • 打赏
  • 举报
回复
mark
zooo 2004-07-02
  • 打赏
  • 举报
回复
cnlamar(无中生有)
怎么去你的BLOG啊?
cnlamar 2004-07-02
  • 打赏
  • 举报
回复
呵呵。。。这个确实是非常的办法:P
cnlamar 2004-07-02
  • 打赏
  • 举报
回复
1S,20W数据而已
1000W数据,按照你的20W/1S的话需要500S,接近10分钟?

我前两天写了个BLOG,介绍了一下,不知道你看了没,呵呵,如果没看,建议你去看看:D
cnlamar 2004-07-02
  • 打赏
  • 举报
回复
我晕,我当然知道这个的差别,而且不是一般的大……在我的方法里肯定只记录了这个ID,如果我用了select * from table我先不光是速度慢,1000W数据,那是根本无法执行的,至少在我机器上绝对是。

我的意思是说,如果你之前可以得知数据范围的准确位置,就不需要再获取ID了,明白否?

仔细看看我在上面的回复,再回复,希望能减少误会……
edobnet 2004-07-01
  • 打赏
  • 举报
回复
=======================
rownum不能支持order by。??????????????????

oracle 8.16,8.17都支持的,
gxboy 2004-07-01
  • 打赏
  • 举报
回复
哈哈,我就是他的那个朋友了,按无中兄的做法,or数据库上亿级是没有点问题的,只要你有1T内存,sqlsrever我敢保证可以上10亿,cpu消耗最多1%。速度就象打开html,哈哈。

http://www.cnblogs.com/gxboy/archive/2004/06/30/19912.aspx

http://61.139.33.122:23094/page

1000W 数据分页。
billy_zh 2004-07-01
  • 打赏
  • 举报
回复
一般来说,我们只会浏览结果的前几十页吧,
我的思路:
1,先取出某页数据的id,
2,再用这些id去检索数据。
显然瓶颈出现在第一步上,随着页数的增加需要遍历更多的记录。

zhengsb 2004-07-01
  • 打赏
  • 举报
回复
mark
cnlamar 2004-07-01
  • 打赏
  • 举报
回复
胖胖,我可没火~~~呵呵,我这人比较喜欢开玩笑,你又不是不知道~~~~

使名扬,这样做,似乎还不如存储过程建临时表(@@)的办法带来的消耗小一些呀。。。。

而无论哪里的瓶颈,一次请求达到那么高的CPU消耗,似乎很难可取。。。
cnlamar 2004-07-01
  • 打赏
  • 举报
回复
瓶颈在那我以前就注意到了,也想了一些对策,不过不是特别理想,没有根本解决,似乎也不太可能根本解决!

我只是说,你如果能直接取到ID,就不用缓存了,不用这样那样,直接取数据就是一样

如果还得先取全部ID,才能确认范围的ID,那不是和我一样了吗?白忙活了...
tongzhenhua 2004-07-01
  • 打赏
  • 举报
回复
to cnlamar(无中生有)

1.
"但SQL SERVER不能这样,着是遗憾:( "


其实sql server也可以这样。不过就是sql上写起来难一点,没有Oracle的方便。另外对于有order by的SQL传入进去的话,有时好像会有点问题。
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/pagercontrols.asp
官方是这样的
SELECT * FROM
(SELECT TOP ItemsPerPage * FROM
(SELECT TOP ItemsPerPage*CurrentPageIndex * FROM
(SelectCommand) AS t0
ORDER BY SortField ASC) AS t1
ORDER BY SortField DESC) AS t2
ORDER BY SortField
以下是我的试验。不过好像很不方便
------


SELECT *
FROM (SELECT TOP 20 *
FROM (SELECT TOP 20 *
FROM (SELECT TOP 20 Employees.LastName, Employees.FirstName,
Orders.OrderID
FROM Employees INNER JOIN
Orders ON
Employees.EmployeeID = Orders.EmployeeID
ORDER BY Orders.OrderID) t0
ORDER BY OrderID) T1
ORDER BY OrderID DESC) DERIVEDTBL
ORDER BY OrderID


------------------------------------
SELECT *
FROM (SELECT TOP 20 *
FROM (SELECT TOP 40 *
FROM (SELECT TOP 20 Employees.LastName, Employees.FirstName,
SUM(Orders.Freight) AS Summ
FROM Employees INNER JOIN
Orders ON
Employees.EmployeeID = Orders.EmployeeID
GROUP BY Employees.LastName, Employees.FirstName
ORDER BY Employees.LastName, Employees.FirstName) t0
ORDER BY LastName, FirstName) T1
ORDER BY LastName, FirstName DESC) t2
ORDER BY LastName, FirstName


可以有多个sort field。比如写上name desc ,age asc,degree但是要求最后一个是非desc的。(即asc的可以不写)

2.CPU消耗好像是高了点。你测试时数据库和web服务器是在同一台机器上么?这个好像没办法。Oracle一打开就要100-200M物理内存+300M虚拟内存。还有其他的进程40来个。另外那个录像一开,什么都不要做就25%了:(。不过这个方法主要是把计算量扔到数据库去处理了。所以在计算时一会下子被Oracle用到100%,然后再恢复。
bobowu 2004-07-01
  • 打赏
  • 举报
回复
学习中
加载更多回复(12)

62,041

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧