一、資料迴圈
用 id > $minId limit 1000 這種方式來迴圈資料。不要用limit 10000,1000這種方式,這種方式在資料量大的時候會非常慢。
用id > $minId limit 1000這種方式來迴圈時,不要再計算分頁,而是要在迴圈中,或者迴圈結束後來改變minId的大小,最後將minId做下記錄(用檔案日誌就行),以免程式需要斷開或者意外斷開時能自動銜接。
示例程式碼(已做刪減,只保留核心程式碼):
while($minId < $processMaxId){
$sql = "select id,title from xx where forbid = 1 and id > '{$minId}' and id <= '{$processMaxId}' order by id asc limit {$pageSize}";
$data = $dbLink->getAll($sql);
if($data){
$insertSql = "insert into xx (askid,`type`,url,addtime,`from`,word,lasttime,asktime,replyid,patchNum) values ";
foreach ($data as $k => $v){
if($askId > $minId){
$minId = $askId;
}
**UNSET($REPLYLIST,$ASKINFO,$NOW,$ADDTIME,$ASKTIME,$LASTTIME,$FLAG,$ASKID,$TITLE,$CONTENT);**
}
$insertSql = rtrim($insertSql,",");
$dbLink->query($insertSql);
**UNSET($NOW,$PROCESSSTAGE,$DATA,$LOGSQL,$ASKID);**
}else{
$minId += $pageSize;
}
}
**unset($data,$now,$processStage,$logSql);**
二、每一層迴圈結束後,清掉所有沒用的變數
三、設定更大的記憶體上限
對於比較消耗記憶體的,可以在指令碼開頭設定一個表達的記憶體上限,避免程式中途因為記憶體達到上限斷掉
ini_set("memory_limit",'3000M');
四、批量插入
insert … values (),()這種
五、多程式
思路,用不同的程式號來區分程式,就像這樣:
php a.php 1
php a.php 2
表示程式1和2。根據程式數來計算每個程式所控制的資料段。比如有100萬資料,開兩個程式,那麼程式1負責0-50萬,程式2負責50萬-100萬。
程式中的資料迴圈和一中將到的迴圈方式一樣,只不過它有個最大id限制。
得到minId和每個程式的最大id:
$minId = file_get_contents($minFile);
$maxId = 1906847;//可以用程式計算max(id)
$processSize = ceil($maxId/5);
$processMaxId = $process * $processSize;
if(!$minId){
$minId = ($process -1 ) * $processSize;
}
在迴圈中:
while($minId < $processMaxId){
$sql = "select id,title from xx_ask where forbid = 1 and id > '{$minId}' and id <= '{$processMaxId}' order by id asc limit {$pageSize}";
##五、程式進度監控
用表來做記錄。記錄指令碼檔案、程式號、總進度、批次等資訊:
六、守護程式
把需要守護的程式放到自動執行中,每隔一段時間進行監控,如果中斷就自動喚起。多程式也適用。
七、多程式管理
程式開關控制。有時候程式碼寫的不完善,需要關掉或者重開,有個指令碼比較方便,不用一個個開、關。
$processNum = $argv[2]; //程式數
$switchButton = $argv[1]; //開關
//自動執行列表
$execLlist = array(
array(//客戶端問答首頁列表
'path' => DIR_PATH.'/Ask/',//檔案路徑
'file' => 'xx.php',//執行檔案
'command' => 'mulfil'//口令
),
/*array(//客戶端問答首頁列表
'path' => DIR_PATH.'/Ask/',//檔案路徑
'file' => 'xx2.php',//執行檔案
'command' => 'mul'//口令
),*/
);
foreach ($execLlist as $val) {
$path = $val['path'];
$file = $val['file'];
$command = $val['command'];
if (!$path || !$file) {
continue;
}
for($i = 0; $i < $processNum;$i++) {
if($i >= 30){
break;
}
$pid = `ps aux|grep "{$file} {$command} {$i} {$processNum}"|grep -v grep|awk '{print $2}'`;
if ($pid) {
if($switchButton) {
echo $path . $file . "此檔案已在執行,請耐心等待\n";
continue;
}else{
$cmd = "kill {$pid}";
exec($cmd);
}
}else{
if($switchButton){
$cmd = "cd {$path};nohup php {$file} {$command} {$i} {$processNum} > /dev/null &";
exec($cmd);
}
}
}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結