繁体   English   中英

在MySQL InnoDB中替换成表极其缓慢

[英]Replace Into Table in MySQL InnoDB extremely slow

使用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 ,但通常需要8个小时才能获得100MB的txt文件。

如何显着提高速度?

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

原因是InnoDB中的重复键错误处理依赖于撤消日志和语句回滚:1。锁定记录。 2.写入update_undo日志以删除标记记录。 3.写入insert_undo日志以插入记录。 4.尝试插入新记录。 5.注意副本。 6.回滚步骤3和2中写入的撤消日志。

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

他们计划在步骤2中检测重复。这样可以避免在这种情况下进行任何回滚。

这里有2条建议:

  1. 如果适用,请使用MyISAM
  2. 使用INSERT INTO ... ON DUPLICATE KEY UPDATE ...等查询INSERT INTO ... ON DUPLICATE KEY UPDATE ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM