MySQL-mysql如何将数据高效分表?
有一个大数据表(数据量上千万),现在想做分表处理,现在设计的做法是使用php程序,根据每列数据的主键user_id值计算出00-63的64个hash值,散列到64个表中,请问在将数据导至新的分表时,除了将每一条数据计算出hash值,再插入到新表的方法外,有没有更高效的方法?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果ID是自增长的话,那用一个循环,配合批量插入,效率应该会高一些,sql语句那边可以换成别的,可以直接把这些内容查出来dump到一个文件里面,然后用load file插入到表里面
$step = 10000;
for($i=0;$i<64;$i++) {
for($j=1;$j<=1000;$j++) {
$ids = array();
for($k=($j-1)*$step;$k<=$step*$j;$k=$k+64) {
$ids[] = $k;
}
$sql = "insert into users_{$i} select * from users where user_id in (".implode(',',$ids).")";
unset($ids);
}
}
非自增长
mysql -h*** -u**** -p**** DB -N -e "select user_id from users" > ids.txt
$fp = fopen('ids.txt','r');
while($line = fgets($fp)) {
$mod = $line % 64;
file_put_contents('ids_'.$mod.'.txt',$line,FILE_APPEND);
}
fclose($fp);
对拆分之后的文件中的ID进行批量选择插入
直接对userid的结尾分表(具体取几位位数则要看数据量)比较好吧。
mysql的分区表在性能上不如直接分表。而直接拿结尾分表的话可以保证数据相对均匀的分布在每个独立的表里面。当然查询的时候也比较方便。
类似的事情做过一次,当时数据会更多一点,有几亿,按userid 取模100分表的,大概过程是这样的:
1.我可以很容易获得我的useid的最大最小值:min_userid,max_userid。这样粗略认为总表的的userid范围为userlist = [min_userid...max_userid]
2.随便用个脚本把userlist处理(mod或者hash)为100个分组:arr0 ... arr99
arr0为[0,10,20,30 ...]
3.根据 2 的结果拼接100个sql语句.
insert into tb_user_0 (select * from tb_user_all where userid in(arr0));
insert into tb_user_1 (select * from tb_user_all where userid in(arr1));
...
insert into tb_user_99 (select * from tb_user_all where userid in(arr99));
4.批量执行。当时几亿不到20分钟就都搞定了。要比逐条数据处理快很多。
注:userid是有索引的。
insert into 分区表_i select * from 历史表 where mod(user_id,64) = i