我一直在导入大型 CSV 数据文件;通常少于 100,000 条记录。我正在使用 PHP 和 MySQL(InnoDB 表)。我需要在 MySQL INSERT
之前使用 PHP 转换一些字段并进行一些文本处理(下面代码中的 process_note_data()
的一部分)。 MySQL的LOAD DATA
不可行,请勿推荐。
我最近尝试通过使用 START TRANSACTION
和 COMMIT
的 MySQL 事务来提高此过程的速度。性能提升令人惊讶。处理时间减少了 20 倍。因此,20 分钟的处理只需要大约 1 分钟。
问题。
1.) 有谁明白为什么会有这样的性能提升(20 分钟到 1 分钟)?
2.) 我是否应该担心 100,000 条记录的交易量有多大?
3.) 我应该关心事务中的大量插入和/或更新吗?
/*
* Customer Notes Data:
* Rows are either a meeting, call or note!
*/
$row = 1;
$data = array();
$fields = array();
$line = '';
$db->query('SET autocommit=0;');
$db->query('START TRANSACTION;');
if (($handle = fopen("modules/".$currentModule."/Data/customernote.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 4096, ',', '"')) !== FALSE && $row < 999000) {
//Row 1 - CSV header row with field names
if ($row == 1) {
$csv_fields = $data;
} elseif ($row > 1) {
$fields = $this->process_note_data($data, $csv_fields, $row);
}
$row++;
} // end while
fclose($handle);
}
$db->query('COMMIT;');
$db->query('SET autocommit=1;');
注意:文本/字段处理是在对 $this->process_note_data()
的调用中完成的,然后调用另一个具有 INSERT
语句代码的帮助程序类。我没有足够的空间来包含所有代码。 $db->query()
是 MySQL 查询的典型数据库对象。
最佳答案
请查看此链接:
https://dev.mysql.com/doc/refman/5.5/en/optimizing-innodb-transaction-management.html
InnoDB must flush the log to disk at each transaction commit if that transaction made modifications to the database. When each change is followed by a commit (as with the default autocommit setting), the I/O throughput of the storage device puts a cap on the number of potential operations per second.
大事务可能会影响提交期间的性能(检查以上)
仅在回滚的情况下,但可以使用某些设置进行优化(查看链接)
关于php - 为什么 TRANSACTION/COMMIT 使用 PHP/MySQL (InnoDB) 提高了性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14675147/