mysql - 简单的 UPDATE 查询在 InnoDB 中比 MyISAM 花费更多时间

标签 mysql database innodb myisam

简单描述:

在我的应用程序 (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);

它运行得很快,输出是:

Time difference: 0

表示它消耗的时间不到一秒。

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

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

然而,令我惊讶的是,这一次花费了更长的时间,并且输出是:

Time difference: 17

它已经消耗了 17 秒。

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

更新:

我还观察到这 17 秒内有大量磁盘事件。

问题:

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

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

最佳答案

我发现问题出在 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服务器,然后性能提升了很多。

If set to 1, InnoDB will flush (fsync) the transaction logs to the disk at each commit, which offers full ACID behavior. If you are willing to compromise this safety, and you are running small transactions, you may set this to 0 or 2 to reduce disk I/O to the logs. Value 0 means that the log is only written to the log file and the log file flushed to disk approximately once per second. Value 2 means the log is written to the log file at each commit, but the log file is only flushed to disk approximately once per second.

innodb_flush_log_at_trx_commit=2

关于mysql - 简单的 UPDATE 查询在 InnoDB 中比 MyISAM 花费更多时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30545353/

相关文章:

mysql - 并发连接中的InnoDB事务隔离级别

mysql - 我可以根据表的最后 100 条记录进行 GROUP BY

java - 在 Swing 应用程序中使用 Hibernate 进行 session 管理

java - 在后台检查互联网

mysql - 如何在安装在 MySql 4 之上的 MySql 5 上启用 inno-db 支持?

mysql - 在具有 160M+ 行的 MySQL InnoDB 表上,选择查询非常慢

php - 连接 2 个表后未得到所需结果

php - 如何在指定时间后自动从数据库中删除数据?

mysql - 如何合并来自两个独立表的数据?

database - BCNF:寻找实际使用 super key 而不是候选 key 的示例