【问题标题】:Simple UPDATE query takes too much time in InnoDB than MyISAM简单的 UPDATE 查询在 InnoDB 中比 MyISAM 花费的时间太多
【发布时间】:2015-05-30 11:04:01
【问题描述】:

简要说明:

在我的应用程序 (VC++/Windows 8) 中,我发出简单的更新查询以增加 MySQL 数据库中 InnoDB 表中字段的值。与 MyISAM 表相比,它花费的时间太长了。

详情:

我正在创建一个表DEMO_TABLE,其中包含MyIDMyCounter 列(均为整数)和引擎MyISAM

pStatement->execute("CREATE TABLE IF NOT EXISTS DEMO_TABLE(MyID int NOT NULL PRIMARY KEY, MyCounter int) ENGINE=MyISAM");

然后我在表中添加了一个 MyID 值等于 0 的行。然后我在循环中发出 UPDATE 查询:

time_t dwTime1 = time(&dwTime1);
for (int i=0; i<500; i++)
{
    char strUpdateRequest[256];
    sprintf_s(strUpdateRequest, 256, "UPDATE DEMO_TABLE SET MyCounter = (MyCounter + 1) WHERE ThreadID = 0");
    pStatement->executeUpdate(strUpdateRequest);
}
time_t dwTime2 = time(&dwTime2);
std::cout << "\nTime difference: " << (dwTime2 - dwTime1);

它跑得很快,输出是:

时差:0

意味着它消耗了不到一秒。

但是当我删除表并使用InnoDB 引擎再次重复所有这些练习时。

pStatement->execute("CREATE TABLE IF NOT EXISTS DEMO_TABLE(ThreadID int NOT NULL PRIMARY KEY, MyCounter int) ENGINE=InnoDB");

但是,令我惊讶的是,这一次花了更长的时间,输出结果是:

时差:17

已经消耗了 17 秒。

(尽管在上述两种情况下,我检查了表包含并发现​​MyCounter 列值已正确填充(500))

更新:

我还观察到这 17 秒内有很多磁盘活动。

问题:

在许多讨论中,甚至在 MySQL 文档中,都提到在更新的情况下,InnoDB 的性能比 MyISAM 好得多。但我观察到的恰恰相反。

有人可以澄清这种行为吗?我做错什么了吗?

【问题讨论】:

  • 您可能需要提交每个更新或在您的库中启用autocommit。此外,请检查大量更新,例如10,000 和同时在多行上。与 MyISAM 的表级锁定相比,InnoDB 受益于行级锁定,在这里您只处理测试中的一行。

标签: mysql database innodb myisam


【解决方案1】:

我发现问题出在 my.ini 中(可以位于 C:\ProgramData\MySQL\MySQL Server 5.6 或基于安装的类似文件夹中)

参数innodb_flush_log_at_trx_commit 的值默认为零,导致每次提交时将1 MB 的innodb_log_buffer_size 写入磁盘。这导致了严重的性能损失。

所以我看了innodb_flush_log_at_trx_commit=2的描述,然后重启了MySQL服务器,性能提升了很多。

如果设置为 1,InnoDB 会将事务日志刷新(fsync)到 每次提交时的磁盘,它提供了完整的 ACID 行为。如果你是 愿意牺牲这种安全性,而你的规模很小 事务,您可以将其设置为 0 或 2 以减少磁盘 I/O 到 日志。值 0 表示日志只写入日志文件,并且 日志文件大约每秒刷新一次到磁盘。价值 2 表示在每次提交时将日志写入日志文件,但日志 文件大约每秒刷新一次到磁盘。

innodb_flush_log_at_trx_commit=2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-06
    • 2018-01-08
    • 2019-11-14
    • 2012-09-03
    • 2013-07-11
    • 2017-09-24
    • 1970-01-01
    相关资源
    最近更新 更多