| 方案 | 耗時 (100 萬行) | 備註 |
|---|---|---|
| Stored Procedure 迴圈 INSERT | 58 分 30 秒 | 語句解析/提交開銷極大 |
| PHP 生成 TSV + LOAD DATA | ~1 分鐘 | 繞過 SQL 層,極速 |
<?php
$t = microtime(true);
set_time_limit(0);
$f = fopen('e:/insert.sql', 'wb');
$row = "268\t2\t'0,262,268,'\t0\t'2342'\t'423423'\t'123123'\t'2012-01-09 09:55:43'\t'upload/a.jpg'\t'upload/thumb_a.jpg'\tNULL\tNULL\t38\t'件'\t''\t123\t123\t0";
for ($i=0; $i<1000000; $i++) {
fwrite($f, $row . "\r\n");
}
fclose($f);
echo "寫入完成,耗時: " . (microtime(true)-$t) . " 秒";
\t 分隔,行用 \r\n 結尾。NULL (不加引號)。LOAD DATA LOCAL INFILE 'e:/insert.sql'
INTO TABLE tenmillion
FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\r\n'
(categ_id, categ_fid, SortPath, address, p_identifier, pro_specification, name, description, add_date, picture_url, thumb_url, shop_url, shop_thumb_url, brand_id, unit, square_meters_unit, market_price, true_price, square_meters_price);
LOCAL 表示檔案在 Client 端,由 Client 讀取傳給 Server。-- 假設 itemid 為自增主鍵
INSERT INTO downitems (chid, catid, softid, ...)
SELECT chid, catid, softid, ...
FROM downitems
WHERE itemid >= (
SELECT FLOOR(RAND() * (SELECT MAX(itemid) FROM downitems))
)
ORDER BY itemid LIMIT 1000;
RAND() * MAX(id) 隨機取樣,避免連續塊鎖爭用。[mysqld]
innodb_buffer_pool_size = 2G # 導入時可暫時調大
innodb_log_file_size = 1G
innodb_flush_log_at_trx_commit = 2
bulk_insert_buffer_size = 256M # MyISAM 專用
key_buffer_size = 512M # MyISAM 專用
**PHP/Shell 落地 TSV/CSV + LOAD DATA** 是生成百萬測試資料的標準最優解:無 SQL 解析開銷、順序寫入、可斷點續傳。純 SQL 方案適合無法落地檔案的受限環境,利用隨機抽樣指數增長同樣高效。