为什么 MySQL 5.7 使用 MAMP 比本地 MySQL 8.0 快得多?
Why is MySQL 5.7 using MAMP so much faster than local MySQL 8.0?
我刚刚从 运行 我的本地 MySQL 数据库从使用 MAMP 支持的 MYSQL v5.7.30 迁移到 v8 的“正常”本地 MySQL 安装.0.22。虽然切换的原因是我想使用 CTE,但我也希望能提高性能,正如经常报道的那样。
虽然我的大多数查询的性能略好 (10-20%),但简单 SELECT count(*) from mytable;
的性能大约需要两倍的时间:3.8s 在 MAMP-MySQL 5.7.30 上对比 7.5s 在 MySQL 8.0.22 上。这是在 table 上,有 15m 行和 12 列,1 个 PK,1 个索引列(除了 PK),没有 FK。
tables 应该与我使用 MySQL Workbench 迁移向导迁移它们完全相同。
在 Whosebug 上搜索可能的性能调整,看起来通常的怀疑可能没有设置为理想值(使用 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 的性能好?
如评论中所问:对于 5.7 和 8.0,我使用 同一台机器,这是一台配备 2.2 GHz 英特尔处理器的相当新的笔记本电脑i7 处理器和 16GB 内存,运行 macOS Catalina。
非常感谢任何指点!
编辑:根据评论中的要求,这里有一些更多的细节:
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, '', ''
TL;DR: 就是这样。
长答案:正如问题的修改版本中所指出的,我发现我尝试过的所有查询实际上在 8.0 上比它们 FASTER在 5.7 - 应该是。唯一的例外似乎是 SELECT COUNT(*)
查询,它莫名其妙地变慢了。但考虑到总体上速度更快,我可以接受。
我刚刚从 运行 我的本地 MySQL 数据库从使用 MAMP 支持的 MYSQL v5.7.30 迁移到 v8 的“正常”本地 MySQL 安装.0.22。虽然切换的原因是我想使用 CTE,但我也希望能提高性能,正如经常报道的那样。
虽然我的大多数查询的性能略好 (10-20%),但简单 SELECT count(*) from mytable;
的性能大约需要两倍的时间:3.8s 在 MAMP-MySQL 5.7.30 上对比 7.5s 在 MySQL 8.0.22 上。这是在 table 上,有 15m 行和 12 列,1 个 PK,1 个索引列(除了 PK),没有 FK。
tables 应该与我使用 MySQL Workbench 迁移向导迁移它们完全相同。
在 Whosebug 上搜索可能的性能调整,看起来通常的怀疑可能没有设置为理想值(使用 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 的性能好?
如评论中所问:对于 5.7 和 8.0,我使用 同一台机器,这是一台配备 2.2 GHz 英特尔处理器的相当新的笔记本电脑i7 处理器和 16GB 内存,运行 macOS Catalina。
非常感谢任何指点!
编辑:根据评论中的要求,这里有一些更多的细节:
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, '', ''
TL;DR: 就是这样。
长答案:正如问题的修改版本中所指出的,我发现我尝试过的所有查询实际上在 8.0 上比它们 FASTER在 5.7 - 应该是。唯一的例外似乎是 SELECT COUNT(*)
查询,它莫名其妙地变慢了。但考虑到总体上速度更快,我可以接受。