mysql - 在 MySQL InnoDB 中替换为表非常慢

标签 mysql mariadb

使用 MySQL(确切地说是 MariaDB)。我有以下脚本,需要每隔一天运行一次以更新我的数据库,但速度慢得令人无法忍受。每个要更新的表都需要运行数小时。这是一个 shell 脚本:

CMD_MYSQL="${MYSQL_DIR}mysql  --local-infile=1 --default-character-set=utf8 --protocol=${MYSQL_PROTOCOL} --port=${MYSQL_PORT} --user=${MYSQL_USER} --pass=${MYSQL_PASS} --host=${MYSQL_HOST} --database=${MYSQL_DB}"

### Update MySQL Data ###
## table name are lowercase
tablename=`echo $FILE | tr "[[:upper:]]" "[[:lower:]]"`
echo "Uploading ($FILE) to ($MYSQL_DB.$tablename) with REPLACE option..."
## let's try with the REPLACE OPTION
$CMD_MYSQL --execute="LOAD DATA LOCAL INFILE '$FILE.txt' REPLACE INTO TABLE $tablename CHARACTER SET utf8 FIELDS TERMINATED BY '|' IGNORE 1 LINES;"
## we need to erase the records, NOT updated today
echo "erasing old records from ($tablename)..."
$CMD_MYSQL --execute="DELETE FROM $tablename WHERE datediff(TimeStamp, now()) < 0;"

您可以安全地忽略文件中其他地方设置的一些变量。 $FILE 通常是由 | 分隔的 txt 文件。每行代表一条记录,示例:

AirportID|AirportCode|AirportName|Latitude|Longitude|MainCityID|CountryCode
6024358|DME|Moscow, Russia (DME-Domodedovo Intl.)|55.414495|37.899907|2395|RU
6024360|DMM|Dammam, Saudi Arabia (DMM-King Fahd Intl.)|26.468075|49.796824|180543|SA

该脚本在现有数据库上运行,其中包含旧记录。然后它检查其最后更新日期,并执行 REPLACE INTO,但对于 100MB 的 txt 文件通常需要 8 个小时。

如何显着提高速度?

最佳答案

此问题会影响所有版本的 InnoDB (4.1+)。在 InnoDB 中替换重复项太慢了。这是 MyISAM 优越的地方。 MyISAM 用了 0.05 秒。

原因是InnoDB中的duplicate key错误处理依赖于undo log和statement rollback: 1.锁定记录。 2. 写入update_undo log 删除标记记录。 3. 写入插入记录的insert_undo log。 4. 尝试插入新记录。 5.注意重复。 6.回滚步骤3和步骤2写入的undo log。

这是 MySQL 中的一个问题,截至 2019 年 9 月尚未在任何版本中修复: https://bugs.mysql.com/bug.php?id=71507

他们计划在第 2 步检测重复项。这将避免在这种情况下发生任何回滚。

这里有两个建议:

  1. 如果适用,使用 MyISAM
  2. 使用诸如 INSERT INTO ... ON DUPLICATE KEY UPDATE ... 之类的查询

关于mysql - 在 MySQL InnoDB 中替换为表非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21485394/

相关文章:

Mysql查询获取两个表之间的信息

mysql - 错误 2002 (HY000) : Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) when I typed "mysql"

mysql - 如何获取 MariaDB 的当前值?

Mysql - LEFT JOIN 方式比 INNER JOIN 更快

mysql - Perl 和 XPath : missing entries in database table

mysql - 代码点火器/MySQL : Column count doesn't match value count with insert_batch()?

c++ - 无法链接到 C++ 的 MySQL 库

mysql - SQL语句4表连接

mysql - 如何使用cmd在SQL中创建存储过程?

sql - 在 Ubuntu 18.04 中完全删除 MariaDB 10.01