数据库 有人告诉我如果数据量大了就不能做分页了?是这样么?

aisensiy · 发布于 2013年05月09日 · 最后由 maddemon 回复于 2013年05月21日 · 12754 次阅读
96
本帖已被设为精华帖!

不懂,自己做的东西从没有遇到过大数据量。

共收到 70 条回复
1249

多大的数据? 目前我30W+的数据,做分页也没有影响。数据量大了,比较影响的是查询,分页影响不大。

115

#1楼 @outman 分页难道不查询么,数据大肯定影响分页。

1249

#2楼 @zgm 分页是分页,查询是查询,分页就是说你把大数据块分成几段,每次只看一小段,这个是很快的,你只要知道每段的起始指针,然后取出那段数据出来,非常快。 查询就不一样了,你要在所有大数据中查找匹配字段,除非针对字段建立索引,不然查询就会很慢。

96

好 谢谢指点,solr 内存索引有必要么

115

#3楼 @outman 数据很大对 offset 的性能没有影响么?

1249

#5楼 @zgm 我最开始就说了,影响不大,而不是一点影响的没有。你想想看,它不就是计算数据大小,然后进行分段处理没。那些ID都是自动建立索引的,如果放在一个数组里面就是计算哈数组大小就可以得到数据长度了,然后再分段处理。当然具体实现可能算法还有不同,所以影响对分页真的不大,相比较查询而言,简直可以忽略不计。

6430

做不做分页不是数据量大不大决定的吧 还是看需求 要是不考虑需求压根不需要分页了就 我也觉得分页对性能的影响可以忽略不计

115

#6楼 @outman 如果数据量对计算数据大小没有影响, 那么 counter cache 是干吗的。

1249

#8楼 @zgm 我没说过没有影响。只是影响不大。到此为止吧。我也不想争论下去了。至于为什么,自己去分析。

96

#8楼 @zgm 我觉得有你在总会这样....

115

#9楼 @outman 你觉得是争论,我觉得是讨论啊,也许我再像你学习呢。

12楼 已删除
6430

#8楼 @zgm 不需要很大计算吧?比如告诉你数据量是1亿 每页10条 那就存page1=1...10 page2=11...20 .........不用涉及具体数据吧? 上面都是我瞎编的 我没研究过 我编不下去了。。。遁走

115

#13楼 @ChanceDoor 我的意思是,可能前100条记录都没有问题,但是到9000多万条的时候,就是 9千万+01 到 9千万+10, 我觉得这里会慢。

4375

事实上有人做个类似的实验,20W条记录分页操作,mysql, postgresql, sqlite 都不怎么理想... http://obmem.info/?p=493

115

#15楼 @saiga 因为我也看过之前淘宝的一个文章, 淘宝产品之所以只有100页,就因为再往后,就比较慢了,我接触过一个有接近 2000万的记录的项目,后面的分页就慢。

115

#10楼 @aisensiy #9楼 @outman 可能我说话的习惯比较让大家不爽,但是我真的是讨论问题,有得罪的地方,不好意思拉。

6430

#14楼 @zgm 恩恩 刚才到项目里看了看 分页确实有影响 但不是分页过程导致的 而是分页之后每次点击某一页 就会取这几页的id进行查询 所以性能还是消耗在查询上 如果不用分页,就相当于一次查询就够了,这属于分页机制的影响吧,而且跟数据量大小无关

96

#12楼 @zgm 没有 我的意思是有你在会把内容挖掘的非常深入·

115

#18楼 @ChanceDoor 可能是这样的, 有可能我刚才和 @outman 理解的分页不是一个意思,我把分页后的查询也算在分页这个过程里面了,那如果单纯的分页,也许 @outman 说的对,没有什么影响。

96

这个问题我遇到过, 为此还重写过will_paginate。 其实原因是由于以前的paginate方法生成的sql是 select * from xxx offset x limit 20, 这样的话mysql性能很差, 由于offset的record也会被scan。 解决问题就是生成类似于 select * from xxx where id > x and id < x + 20的sql, 性能问题就没有了。

96

#17楼 @zgm 还有我不觉得你说话有问题的

115

#22楼 @aisensiy 其实我只是想解决问题,即使问题是你提出来的,对我来说也是学习过程。哈哈。

115

#21楼 @kevinxu 你提出的方案比较可行, select * from xxx where id > x limit y; 但是这种分页只是针对软删除的数据,如果id不连续的话,就不准确了。

196

@kevinxu 現在 will_paginate 還有這樣的問題嗎?

96

#25楼 @xdite 最近一直没有跟~, 不过你可以check一下log

6430

#17楼 @zgm 等一下 你说的是对的 越往后性能越差 4亿直接点last居然内存不足了 但我觉得没道理呀 还是抽空研究一下吧 主要这块不是我写的 不太清楚是什么原因

115

#25楼 @xdite 刚看了一下,还是这样。

96

#25楼 @xdite 话说还得从逻辑上解决这个问题, load more就是不错方案; 另外也可以参考一下豆瓣, 豆瓣的豆油的分页就很诡异, 应该是为了避免分页问题。

115

#27楼 @ChanceDoor 我觉得可能是 offset 造成的,就像 @kevinxu 说的, offset 会 scan 前面的 3亿多。

115

#31楼 @xdite 我们几乎都是 InnoDB 啊。

96

#21楼 @kevinxu select * from xxx where id > x and id < x + 20 如果中间id不连续咋办

96

#34楼 @2forVendetta 你难住我了 :) 我们之前的场景是没有类似需求, 如果再计算非连续id的话 实在有点重了

96

#31楼 @xdite 之前每次count(*)都要take 40s+ :)

96

这里有篇不错的资料,基本上解释了大家的问题 http://www.percona.com/files/presentations/ppc2009/PPC2009_mysql_pagination.pdf

6430

#30楼 @zgm 不是啊 log里的sql语句是

SELECT ... FROM .. WHERE `a`.`id` IN (380715162, 381563334, 383631782, 383986847, 385452709, 322199919, 114884083, 115762227, 124137470, 124137745)

而solr request的parammeters里面有

&start=8506170&rows=10

如果是内存溢出的话根本还没到查询就崩了 断在solr request 我估计还是solr的问题?为什么solr request会随着页数增加而变慢?

115

#35楼 @kevinxu #31楼 @xdite

这个该如何理解

So remember Innodb is not slow for ALL COUNT() queries but only for very specific case of COUNT() query without WHERE clause.

6430

#37楼 @donnior 原来如此。。。

115

#38楼 @ChanceDoor 我也想不明白了。

115

#40楼 @ChanceDoor 我也看了 pdf, mysql 会把 offset 的数据放到内存, 可能还是这个原因。但是你说的问题为什么sql 执行到 solr 死掉就不知道了。

6430

#42楼 @zgm 恩 我再研究研究 应该要看solr是怎么处理request的

115

#43楼 @ChanceDoor 研究好了,再贴出来共享一下哈。

6430

#44楼 @zgm 我靠 不要给我压力啊 研究不出来不是糗大了

115

#45楼 @ChanceDoor 我随便说说你当真拉? 😄

96

#39楼 @zgm 我的理解是Innodb在没有使用where情况下也就是没有使用index, 由于无index同时没有使用primary key(innodb是clustered index, primary key是和data存在一起的)这样的话就是全表的扫描了; 而使用where就可以利用索引从而加速 ; 纯属个人猜想:)

6430

#46楼 @zgm 排序。。。。solr它每次都排序 我猜的 不管咯~

96

简单来说大数据不使用分页的基本原理就是: 使用next n而不是page n来规避掉offset或者limit X, Y

具体做法常见的就是将offset直接转换为范围计算,如id > 10 and id < 20, 或者是时间之类的

6430

#49楼 @donnior 这种分页是will_paginate吗?我用kaminari好像是

SELECT ... FROM .. WHERE `a`.`id` IN (380715162, 381563334, 383631782, 383986847, 385452709, 322199919, 114884083, 115762227, 124137470, 124137745)

这样的啊

115

#50楼 @ChanceDoor 你这个应该是用 solr 搜索后产生的 sql 吧。

6430

#51楼 @zgm 恩恩 是的 在我自己写的另一个里面确实是limit offset 原来是solr自带分页 而且还是用offset的

239

以前碰到过大数据分页,基本上找不到解决方案啊。你去看看淘宝,页面都是有限的比如100页500页,当数据量到达一定的数量,你必须去通过检索功能去减少数据量。offset 说白了还是有瓶颈的,当达到几千万数据,游标移动还是很慢。

De6df3

可以分页,避免全表查询就好了,比如 count 的动作,游标经过的行越多,就越慢

96

数据量大就要避免全表扫描,分页涉及总数问题,而且也要考虑过滤出来的数据有多大的量。为什么用索引呢?为的就是快速的从大数据里面找出少量的数据,然后再进行其他操作。

2880

查询能保持上下文(上一页最后一条的 id)的话就能无限翻下去

否则就是业界标准 100 页... google 都不给你翻到 100 页以后

96

数据量非常大就需要考虑分库分表,将大数据集拆分为小数据集,这样可以保证查询效率,一般会选择根据用户id分表分库,让同一个用户的的数据落在同一个库中

2880

#57楼 @mojidong 手动分库分表的时代已经过去了吧... 现在数据库自带的 clustering 方案都很成熟了

96

@luikore 自带的是不可能满足所有业务需求的,包括扩容,迁移等。

2880

#59楼 @mojidong 业务需求的是 scaling 和查询速度而不是分库分表, 像 mongo db 这种无缝扩容的一开始就没有分库分表这回事, postgres 的话直接把大表改成 uuid 主键马上就能 cluster 扩容了.

手工分表经常就是 sharding 策略没考虑周到, 分完发现分页查询没变快反而变慢了.

至于迁移问题, 主要是手工分表造成的...

96

@luikore mongo db 在实际应用中有丢数据现象,在则我是不敢把交易数据放在里面,mongo不是银弹,不要过分神话。手动分库分表的好处在于,可以灵活的迁移数据,可以有效控制数据库压力,将冷数据放入配置一般的数据库集群上,热数据放在配置较高的集群上,我相信mongo没法满足我这个需求

2880

#61楼 @mojidong 现象都有原因, 你这个"丢数据的现象"指的是好多年前的 bug, 还是读到的过时网志, 还是亲身碰到了无法解释? 不喜欢 mongodb 的话可以选择 pg. mysql 最近没关注, 应该也有不少针对大数据量 scaling 的修改.

再就是 mongo 是可以自定 sharding 策略的, 完全可以做到按冷热数据分类. 没看文档吧...

96

@luikore mongodb 用的比较早,现在没怎么用了。 自己做灵活可控,用其他自带方案第一个是不一定能满足需求,第二个就是出现bug是我们不能够承受的,不可能等到他下一个版本fix。最终还是要自己写中间件。

96

如果只是Write Once, Read Many Times的大数据,可以采用Hadoop策略,Sqoop的Data integration可以把关系型数据库里数据抓取到HDFS。

1754

#39楼 @zgm #47楼 @kevinxu 差不多是 47楼的意思,但不完全是,where条件加上也不一定会触发索引,不过加上where条件,不管触发索引与否,都不会全表扫描。如果我没记错的话。

580

我们项目中使用mongodb,某张表有80万记录。有2种业务情况: 一,在后台,管理员有查询功能: 开始,使用kaminari插件分页 page(params[:page]).per(20) ),速度很慢; 然后,使用了limit(20).skip(skip_page*20),避免count操作,速度有所提升,但还是慢; 最后,使用了where({:_id.gt=>last_id}).limit(20),避免skip操作,传递每页最后一个记录id的方式,速度快。缺点是只有"下一页"这个链接,但是足够管理员使用了。

二,在前台,用户浏览数据时有分页。 我们是把100页的数据的id放在redis的Sorted set中,通过redis的ZRANGE方法和kaminari插件的Kaminari.paginate_array方法(传入redis中记录的count值)来进行分页,速度快。100页以后的数据,是从mongodb中读取的,速度慢。

5210

@kevinxu 那个。。。count(*)和count(1)的成本是不一样的

De6df3

#66楼 @helloqidi 加 total_entries 参数

1

我说说 CSDN BBS 的方案,把 topic_id, forum_id, status 这些列表用到的字段单独放到一张内存表加索引,查几千页没问题。

http://bbs.csdn.net/forums/DotNET?page=3500

3001

查询的关键就是避开大量的扫描,分页之所以慢是skip的太多。所以避开skip就可以了。如何避开?排序、条件、找ID。 比如第10000页,那么只要能查到找到10000页的最小ID就可以了。 select MAX(id) 虽然牵扯的数据范围比较广,但对于数据的扫描少的狠(只在Btree上N分查找),所以效率很高。

71楼 已删除
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册