【发布时间】:2020-11-22 21:53:54
【问题描述】:
我刚刚从使用支持 MAMP 的 MYSQL v5.7.30 运行本地 MySQL 数据库转移到 v8.0.22 的“正常”本地 MySQL 安装。虽然切换的原因是我想使用 CTE,但我也希望能提高性能,正如经常报道的那样。
虽然我的大多数查询的性能略好 (10-20%),但简单的 SELECT count(*) from mytable; 的性能需要大约两倍的时间:在 MAMP-MySQL 5.7 上 3.8s。在 MySQL 8.0.22 上为 30 与 7.5s。这是在一个有 15m 行和 12 列的表上,1 个 PK,1 个索引列(除了 PK),没有 FK。
这些表应该与我使用 MySQL Workbench 迁移向导迁移它们时完全相同。
在 Stackoverflow 中搜索可能的性能调整,看起来通常的嫌疑人可能没有设置为理想值(使用 MySQL 的开箱即用设置),但它们至少在我的两个数据库之间是相同的:
SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; # 134217728 = 128MB
SHOW VARIABLES LIKE 'innodb_log_file_size'; # 50331648 = 48MB
SHOW VARIABLES LIKE 'innodb_buffer_pool_instances'; # 1
所以问题是:为什么 COUNT(*) 语句的性能会差这么多,我怎样才能让 MySQL 8.0 的性能与 MySQL 5.7 一样?
正如 cmets 中所问的那样:对于 5.7 和 8.0,我使用同一台机器,这是一款相当新的笔记本电脑,配备 2.2 GHz 英特尔 i7 处理器和 16GB 内存,运行 macOS Catalina。
任何指针都非常感谢!
编辑:根据 cmets 的要求,这里有更多细节:
1 - SHOW CREATE TABLE mytable
对于 5.7:
CREATE TABLE `mytable` (
`var1` int(11) NOT NULL,
`var2` datetime(6) NOT NULL,
`var3` datetime(6) NOT NULL,
`var4` datetime(6) DEFAULT NULL,
`var5` datetime(6) DEFAULT NULL,
`var6` datetime(6) DEFAULT NULL,
`var7` decimal(6,2) DEFAULT NULL,
`var8` text,
`var9` text,
`var10` text,
`var11` text,
`var12` int(11) DEFAULT NULL,
PRIMARY KEY (`var1`),
KEY `idx_var12` (`var12`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
对于 8.0:
CREATE TABLE `mytable` (
`var1` int NOT NULL,
`var2` datetime(6) NOT NULL,
`var3` datetime(6) NOT NULL,
`var4` datetime(6) DEFAULT NULL,
`var5` datetime(6) DEFAULT NULL,
`var6` datetime(6) DEFAULT NULL,
`var7` decimal(6,2) DEFAULT NULL,
`var8` text,
`var9` text,
`var10` text,
`var11` text,
`var12` int DEFAULT NULL,
PRIMARY KEY (`var1`),
KEY `idx_var12` (`var12`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
2 - EXPLAIN SELECT count(*) from mytable;
对于 8.0 和 5.7:
# id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows, filtered, Extra
'1', 'SIMPLE', 'mytable', NULL, 'index', NULL, 'idx_var12', '5', NULL, '15480019', '100.00', 'Using index'
3 - SHOW FULL PROCESSLIST;
对于 5.7:
# Id, User, Host, db, Command, Time, State, Info
'682', 'root', 'localhost:64503', 'testdb', 'Sleep', '178', '', NULL
'683', 'root', 'localhost:64504', 'testdb', 'Query', '0', 'starting', 'SHOW FULL PROCESSLIST'
对于 8.0:
# Id, User, Host, db, Command, Time, State, Info
'5', 'event_scheduler', 'localhost', NULL, 'Daemon', '1545', 'Waiting on empty queue', NULL
'8', 'root', 'localhost:65524', 'my_schema', 'Query', '0', 'init', 'SHOW FULL PROCESSLIST'
'9', 'root', 'localhost:65525', 'my_schema', 'Sleep', '284', '', NULL
4 - SHOW TABLE STATUS WHERE name = 'mytable';
对于 5.7:
# Name, Engine, Version, Row_format, Rows, Avg_row_length, Data_length, Max_data_length, Index_length, Data_free, Auto_increment, Create_time, Update_time, Check_time, Collation, Checksum, Create_options, Comment
'mytable', 'InnoDB', '10', 'Dynamic', '15480019', '168', '2611986432', '0', '261898240', '6291456', NULL, '2020-11-17 23:03:04', NULL, NULL, 'utf8_general_ci', NULL, '', ''
对于 8.0:
# Name, Engine, Version, Row_format, Rows, Avg_row_length, Data_length, Max_data_length, Index_length, Data_free, Auto_increment, Create_time, Update_time, Check_time, Collation, Checksum, Create_options, Comment
'mytable', 'InnoDB', '10', 'Dynamic', '14009911', '148', '2081423360', '0', '313507840', '6291456', NULL, '2020-11-22 21:03:29', '2020-11-22 21:17:55', NULL, 'utf8_general_ci', NULL, '', ''
【问题讨论】:
-
请发布每台机器的文本结果,A) SHOW CREATE TABLE mytable;和 B) 从 mytable 中解释 SELECT count(*);进行比较。我们不想看到您是如何创建表的,而是查看 SHOW CREATE TABLE mytable 的结果;请。
-
请在您的 8.0 设备上发布类似于 HTOP 或 TOP 的 TEXT 结果。
-
FWIW、
int(11)和int是相同的。 MySQL 8.0 终于摆脱了整数的多余和令人困惑的大小,因为它并不重要。见stackoverflow.com/a/3135854/20860 -
@Sebastian 将确定从 8.0 开始查询 SELECT count(var1) from mytable 的时间;请比较一下。您是否在应用程序中使用 EVENT_SCHEDULER 功能?您可以通过 SELECT GLOBAL STATUS LIKE '%event%';请发布评估结果。如果我们可以关闭 EVENT_SCHEDULER,您可以释放一些 CPU 周期。请参阅 8.0 参考手册。
-
请从 5.7 实例和 8.0 实例请求更多信息。 # 核心,您的单台机器上是否有任何 SSD 或 NVME 设备支持这两个实例?在 pastebin.com 上发布并分享链接。从您的 SSH 登录根目录中,文本结果为:B) SHOW GLOBAL STATUS;至少 24 小时正常运行时间后 C) 显示全局变量; D) 显示完整的处理程序; F) 显示 ENGINE INNODB 状态; G) 状态;为服务器工作负载调优分析提供建议。