面對 PM 給的幾十萬行 TXT 數據文件,如何快速、穩定導入數據庫?本文提供從簡單 explode 到百萬級優化的完整方案。
$content = file_get_contents("serial_number.txt");
$contents = explode(",", $content);
foreach ($contents as $k => $v) {
mysql_query("INSERT INTO serial_number (id, serial_number) VALUES ($k, '$v')");
}
缺點:頻繁往返數據庫,性能極差。
function loadTxtDataIntoDatabase($splitChar, $file, $table, $conn, $fields=[], $insertType='INSERT') {
$head = empty($fields)
? "{$insertType} INTO `{$table}` VALUES('"
: "{$insertType} INTO `{$table}`(`".implode('`,`',$fields)."`) VALUES('";
$end = "')";
$sqldata = trim(file_get_contents($file));
// 統一換行符為 ),(
$sqldata = preg_replace('/(\s*)(\n+)(\s*)/i', "'),('", $sqldata);
// 替換分隔符
if (preg_replace('/\s*/i','',$splitChar) == '') {
$sqldata = preg_replace('/(\w+)(\s+)/i', "$1','", $sqldata);
} else {
$sqldata = str_replace($splitChar, "','", $sqldata);
}
$query = $head . $sqldata . $end;
return mysql_query($query, $conn);
}
| 數據量 | 耗時 |
|---|---|
| 10 萬行 | 2.55 秒 |
| 100 萬行 | 19.68 秒 |
max_allowed_packet=20Mfgets() 流式讀取,分批構建 SQLREPLACE INTO 或 INSERT IGNORE// 示例 1:管道分隔
loadTxtDataIntoDatabase('|', 'sqldata1.txt', 'cengji', $conn, ['id','parentid','name']);
// 示例 2:空格/Tab 分隔
loadTxtDataIntoDatabase(' ', 'sqldata2.txt', 'cars', $conn, ['id','make','model','year']);
// 示例 3:REPLACE 模式
loadTxtDataIntoDatabase("\t", 'sqldata3.txt', 'cars', $conn, ['id','make','model','year'], 'REPLACE');
此方案通過單條 SQL 批量寫入,減少網絡往返 99%+,是中小數據量導入的最佳選擇。