首页 > 解决方案 > 45Mb 表需要写入约 5Gb 字节来插入数据 PHP SQL PDO

问题描述

尝试插入 1 000 000 行(每行 10 个字符),执行命令大约需要 140 秒,提交命令大约需要 48 秒。完成后,表的权重为 45Mb,但 Activity Monitor 表示 mysqld 占用了 5Gb,写入速度约为 40Mb/秒。另一个例子:一天前我也在做同样的事情,但是有 30 000 000 行(phpMyAdmin 中为 1.3Gb),但活动监视器说 mysqld 写了 950Gb(~1Tb)。所以我的问题是这里发生了什么?我的意思是我不想杀死我的SSD...

MAMP 5.7 (396)
macOS Catalina 10.15.7 (19H114)
MacBook Pro 13" 2019 SSD 256Gb RAM 8Gb
running code through terminal
$dbh = new PDO('mysql:host=localhost:8889;dbname=my', $user, $password);
$sql = "CREATE TABLE IF NOT EXISTS `test1` ( `ID` char(10) NOT NULL, PRIMARY KEY (`ID`) );";
$dbh->exec($sql);
$handle = fopen("./lines/30000000.txt", "r");
if ($handle) {
  while (($line = fgets($handle)) !== false) {
     $trimmed_line = trim($line);
     $sth = $dbh->prepare("INSERT IGNORE INTO `test1` SET `ID` = :ID");
     $sth->execute(array('ID' => $trimmed_line));
  }
  fclose($handle); 
}

     //or in the while loop
     array_push($array_of_lines, $trimmed_line);
     if (count($array_of_lines) >= 3000) {
        $sth = $dbh->prepare("INSERT IGNORE INTO test1 SET ID = :ID");
        $dbh->beginTransaction();
        foreach ($array_of_lines as $line) {
           $sth->execute(['ID' => $line]);
        }
        $dbh->commit();
        $array_of_lines = [];
     }
   }
   if (count($array_of_lines)) {
      //commit the last lines
   }

30000000.txt 看起来像这样:

owehfowffu
lrehgeorhw
lirewkhfwe
idhfwuiefo
...
30 000 000 unique lines

phpMyAdmin 47.6Mb 1 000 000 行

活动监视器 2.9Gb 和 33Mb/秒,同时插入 47.6mb 1 000 000 行

标签: phpmysqlpdomemory-leaks

解决方案


推荐阅读