为什么TRANSAGE / COMMIT使用PHP / MySQL(InnoDB)可以大大提高性能?

2022-08-30 12:56:47

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

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

问题。

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;');

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


答案 1
  1. 请检查此链接:

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

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

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

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


答案 2

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

插入 1 条记录,无事务:60 毫秒

插入 1 条记录,使用事务:158 毫秒

插入 200 条使用事务的记录,每条记录后提交:17778 毫秒

插入 200 条无事务记录:4940 毫秒

插入 200 条使用事务的记录,仅在最后一条记录之后提交:4552 毫秒

使用事务插入 1000 条记录,仅在最后一条记录之后提交:21795 毫秒

客户端在丹麦,服务器在比利时(谷歌云f1-micro)。

我打算把它放在评论中,但格式不好....所以这是我提前道歉;-)


推荐