单表 5 千万计划分表,想知道分表后如何分页?

2018-04-03 12:23:10 +08:00
 Aluhao
单表 5 千万了,数据量也继续上涨,想把表拆分成 10 个;
article_comments_0
article_comments_100
我现在想统计一下总数都得这样查询:
function get_count_comments() {
$aid = 0;
for($i = 0; $i < 100; $i++) {
$num += $this->db->result("SELECT COUNT(*) FROM article_comments_'.(string)$i);
}
return $num;
}
for 100 次呀,列表还没查呢,还有没更好的方法?

列表分页有什么好的解决方案,期待 V2 高手解答一下;
10792 次点击
所在节点    MySQL
21 条回复
huyi23
2018-04-03 12:29:29 +08:00
没有,下一个
murmur
2018-04-03 12:31:14 +08:00
分表 count 本身就很蛋疼 计数器必须单独存一个字段里 我记得是 innodb 和 myisam 有一个 count 得行扫的 千万级刚得住?
hcymk2
2018-04-03 12:31:30 +08:00
请不要土法上马,找个中间件,或者用 mysql 的 partition
jy01264313
2018-04-03 12:33:29 +08:00
merge 引擎可以把表逻辑合并在一起
woodface2233
2018-04-03 12:38:49 +08:00
这在每个公司都算是核心技术了吧
capric
2018-04-03 12:48:25 +08:00
二次查找,获取全局视野,修正 offset
fox0001
2018-04-03 13:09:03 +08:00
其实,有用户会关心 5 千万的总数,或者总页数吗?楼主会不会被自己的设计坑了?

总的来说,还是取巧吧。

1 ) N 年前的数据一般没人关心,可以只把近期的数据取出来做分页。例如近几年的数据。

2 )采用异步任务获取数据。比如界面新建任务,后台用定时任务查询数据,任务结束后通知用户

3 )采用缓存,记录总的数量。如果记录是固定的,甚至每页的数据 ID、标题都可以缓存起来。具体要看某条数据的内容,拿 ID 去查数据库。

4 )确实要五千万实时查询,可以借助其它系统或工具,这就不是一个 MySQL 能简单处理的了。例如 Solr、Hadoop 等

具体还是要看楼主的需求。
jixiangqd
2018-04-03 13:19:02 +08:00
partition 正解。。。
realpg
2018-04-03 13:26:16 +08:00
问 dba 去

理想状态,这种库上的触发器都应该一大堆 用来维护各种人工辅助数据
iyaozhen
2018-04-03 13:34:19 +08:00
几亿条内数据用 MySQL 自带的 partition 足够了,注意选好表分区字段,查询的时候必须带上。当然你要直接这样 count 谁也救不了你
Aluhao
2018-04-03 13:46:50 +08:00
@fox0001 谢谢,学习了,我也是这样想,把数据按年拆分出来;
article_comments_2005
~
article_comments_2018
按年拆分,然后根据不同的时间去检索,有人试过没?
ty89
2018-04-03 14:03:31 +08:00
很好奇到底是什么需求,需要把几千万的数据翻页看完
Aluhao
2018-04-03 14:21:05 +08:00
@ty89 其实也不是全部需要翻页;
大致需求就是用户信息推送围绕关注,如关注某个人,某个话题,某个文章,某个新闻,这样的逻辑就需要把所有旧的数据聚合起来,然后分页显示;
snail00
2018-04-03 14:28:44 +08:00
第一, hash 平均分一下, 统计一个表的数量, 不超过 50w, 再乘表个数就行.

第二, 每个表 50w 条, 整个中间表, 维护这些表的信息, 一个表满了, 换下一个, 方便扩充, 表的信息找中间表查.

第三, 用中间件, 数据库只做精准查询.

第四, 冷热数据分开, N 长时间没人看的数据打包到一个表, 加个自增字段维护.
opengps
2018-04-03 17:03:24 +08:00
五千万建议先考虑表分区
crazyneo
2018-04-03 20:31:41 +08:00
首先,单表 5000 万并不需要分表,极端一点的情况就是考虑下表分区。
其次,不要在 5.7 版本以前的 MySQL 中执行 count,无解,带条件尤甚。
5.7 的 InnoDB 提供了 records 接口统计,https://dev.mysql.com/worklog/task/?id=6742
以及官方提及的“ The next worklog, WL#6605, is intended to return the COUNT(*) through this handler::records() interface almost immediately in all conditions just by keeping track if the base committed count along with transaction deltas ”
linyinma
2018-04-04 10:42:54 +08:00
楼主在说什么呢,表太大就想到的是拆表,思路是正确的, 但怎么可能是脱离业务需求,采用平均拆表这种小学生的都能想到的办法呢?

得结合业务,比如日常查询条件频率进行拆分,如果所有的表都属于高频率查询范围,业务上可以采用间接的办法,比如结合 NOSQL 进行查询;

总之一句话 单个再优秀程序也是禁不起不假思索的使用,合理的利用工具也是非常重要的
Aluhao
2018-04-04 11:20:00 +08:00
你们有人用过 TIDB 分布式 NewSQL 数据库么,它的数据结构和语法和 MYSQL 差不多呀。
我一直在看,是不是把数据转到这里会不会好一些,就不用再分表了;
xiebruce
2019-04-29 16:00:50 +08:00
有点好奇边缘数据怎么处理,假如一页 10 条,其中几条在前一个表,有几条在后一个表,怎么处理?哈哈
Aluhao
2019-04-29 20:34:45 +08:00
@xiebruce 我以前是这么做的,如果是列表,我都是输出数据再写入临时表,一般存几十页,如果有更新再处理
现在没按这方式处理了,好麻烦

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/443872

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX