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 關注
- 544 瀏覽
添加回答
舉報