11 回答
TA贡献1845条经验 获得超8个赞
因为代码里面$data数组随着循环次数增加,保存了库中所有的记录,
所以这不是set_time_limit和memory_limit太小的问题,需要优化代码,
可以在第二个foreach后面增加unset($data)释放内存。
然后这个查询子句limit的offset会随着循环次数增加,变得很大,后面的SQL查询肯定会很慢,
如果主键id是连续的,可以考虑使用where id in (....)来获取数据。
每次返回10000条记录占用内存也很大,$goodsModel可以使用yield来降低内存使用。
另外,还有更简单的 分表方式,直接在数据库中写SQL就行。
CREATE TABLE goods_1
CREATE TABLE goods_2
...
CREATE TABLE goods_10
..
INSERT INTO goods_1 SELECT * FROM goods WHERE id MOD 250000 = 0
INSERT INTO goods_2 SELECT * FROM goods WHERE id MOD 250000 = 1
...
INSERT INTO goods_10 SELECT * FROM goods WHERE id MOD 250000 = 9
分表以后之前的代码也许都需要改,这点也是需要考虑的,如果改代码代价很大,可以实施分区(PARTITION)策略。
TA贡献1785条经验 获得超4个赞
你这个其实直接用mysql来做可能要快太多,你这个用的hash处理的,你直接可以
Insert into Table2(field1,field2,...) select value1,value2,... from Table1
后续按照你hash的加个条件。简直不要太快。
以下为答案补充
其实,我这里不是很清楚你这个hash是怎么样的一个算法,但是,我就假设你现在是基于这个商品ID来处理数据的;
那么假设你的,如果是自定义的hash的话,就还需要使用mysql的存储过程了。
以下我以一个测试表俩举例子
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`value` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
# 以上test表假设是原表,然后新创建0~9十个表,那么以下10条sql可以直接把原表数据快速拆分放到新的10个表
INSERT INTO test_0(value) SELECT `value` FROM test WHERE id % 10 = 0;
INSERT INTO test_1(value) SELECT `value` FROM test WHERE id % 10 = 1;
INSERT INTO test_2(value) SELECT `value` FROM test WHERE id % 10 = 2;
INSERT INTO test_3(value) SELECT `value` FROM test WHERE id % 10 = 3;
INSERT INTO test_4(value) SELECT `value` FROM test WHERE id % 10 = 4;
INSERT INTO test_5(value) SELECT `value` FROM test WHERE id % 10 = 5;
INSERT INTO test_6(value) SELECT `value` FROM test WHERE id % 10 = 6;
INSERT INTO test_7(value) SELECT `value` FROM test WHERE id % 10 = 7;
INSERT INTO test_8(value) SELECT `value` FROM test WHERE id % 10 = 8;
INSERT INTO test_9(value) SELECT `value` FROM test WHERE id % 10 = 9;
我好像没看到你的hash是怎么实现的,如果知道的话,我也可以做个测试的来模拟,如果是hash商品编码的话,需要用到存储过程,相对来说又会复杂了一些。
TA贡献1820条经验 获得超10个赞
有过类似经验,你可以了解一下 swoole 异步任务,你250万的数据,根据ID区间来划分,开启25个task进程,投递25个task任务,每个进程也才10W的数据,非常快就能执行完成,并且在cli命令行环境也不存在超时的问题。
TA贡献1858条经验 获得超8个赞
我的想法是新产生的数据就按你分库分表规则处理,已有数据能不动就不动了。如果已产生的数据一定要拆分,对PHP单独处理数据而言这个数据量太大了,用PHP做多层嵌套循环,效率低,易超时。。。看能不能考虑用python来实现数据处理。个人想法,不足之处请谅解。
- 11 回答
- 0 关注
- 508 浏览
添加回答
举报