为什么TRANSACTION/COMMIT使用PHP/MySQL(InnoDB)提高了性能?

jjw*_*ign 32 php mysql csv innodb transactions

我一直在导入大量CSV数据文件; 通常少于100,000条记录.我正在使用PHP和MySQL(InnoDB表).我需要使用PHP来转换某些字段并在MySQL之前进行一些文本处理INSERT(process_note_data()下面代码的一部分).MySQL LOAD DATA是不可行的,所以请不要建议.

我最近尝试使用START TRANSACTION和使用MySQL事务来提高此过程的速度COMMIT.性能提升令人惊讶.处理时间减少了20倍.因此,20分钟的处理只需要大约1分钟.

质询.

1.)有谁理解为什么有这样的性能提升(20分钟到1分钟)?

2.)我应该关注10万条记录的交易量有多大?

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;');
Run Code Online (Sandbox Code Playgroud)

注意:文本/字段处理在调用中完成$this->process_note_data(),然后调用另一个具有INSERT语句代码的辅助类.我没有足够的空间来包含所有代码.$db->query()是MySQL查询的典型数据库对象.

小智 23

  1. 请检查此链接:

    https://dev.mysql.com/doc/refman/5.5/en/optimizing-innodb-transaction-management.html

    如果该事务对数据库进行了修改,InnoDB必须在每次事务提交时将日志刷新到磁盘.当每次更改后都提交时(与默认的自动提交设置一样),存储设备的I/O吞吐量会限制每秒潜在操作的数量.

  2. 大事务可能会影响提交期间的性能(上面检查)

  3. 仅在回滚的情况下,可以使用某些设置进行优化(检查链接)


MrC*_*vin 19

我自己在.Net中的小测试(4个字段pr.记录):

INSERT 1记录,无事务:60 ms

INSERT 1记录,使用事务:158毫秒

使用事务INSERT 200记录,在每条记录后提交:17778 ms

使用无事务INSERT 200记录:4940 ms

使用事务INSERT 200记录,仅在最后一条记录后提交:4552 ms

使用事务INSERT 1000记录,仅在最后一条记录后提交:21795 ms

丹麦的客户,比利时的服务器(谷歌云f1-micro).

我的意思是把它放在评论中,但格式不好....所以这是我的事先道歉;-)

  • 只有200条记录,你不会看到太多差异.拥有超过100,000条记录,您应该开始看到一个巨大的性能优势. (13认同)