我有两个用于测试的数据库设置(因此没有实时数据或连接)。
第一个是5.5.57
充当主数据库的 MySQL 数据库。第二个是5.7.23
充当奴隶的 MySQL 数据库。它Statement Based Replication
在 MySQL 5.5 和Row Based Replication
MySQL 5.7 上运行。
出于某种原因,较大的查询在 MySQL 5.7 上似乎需要更长的时间。例如我有下表:
CREATE TABLE `test1` (
`col0` int(11) DEFAULT NULL,
`col1` int(11) DEFAULT NULL,
`col2` datetime DEFAULT NULL,
`col3 datetime DEFAULT NULL,
`col4` int(11) DEFAULT NULL,
`col5` int(11) DEFAULT NULL,
`col6` int(11) DEFAULT NULL,
`col7` int(4) DEFAULT NULL,
`col8` int(11) DEFAULT NULL,
`col9` datetime DEFAULT NULL,
`col10` datetime DEFAULT NULL,
`UniqRef` int(10) unsigned NOT NULL AUTO_INCREMENT,
`col11` tinyint(1) unsigned NOT NULL DEFAULT '0',
`col12` tinyint(1) unsigned zerofill DEFAULT NULL,
`col13` tinyint(1) unsigned DEFAULT NULL,
PRIMARY KEY (`UniqRef`),
KEY `col0` (`col0`),
KEY `col3` (`col3`),
KEY `col4` (`col4`),
KEY `col8` (`col8`),
KEY `col5` (`col5`),
KEY `col10` (`Deleted`),
KEY `col2` (`col2`),
KEY `col12` (`col12`) USING BTREE,
KEY `col13` (`col13`)
) ENGINE=InnoDB AUTO_INCREMENT=400046649 DEFAULT CHARSET=latin1;
该表的大小为 21GB,包含 83261829 行(使用count(*)
)。
如果我运行查询:
UPDATE test.test1 SET col9 = NOW() WHERE UniqRef IN ('397958600','397940686','397940704','397940678','397. . . . .
该查询包含 6945 个 uniqref 条目。它在 MySQL 5.5 上几乎立即运行,但随后复制到 MySQL 5.7 并需要 90 秒才能运行。
我已经更改了各种设置,但到目前为止它们没有任何区别:
SET @@global.slave_compressed_protocol = 0;
SET @@global.sync_binlog = 0;
set @@global.range_optimizer_max_mem_size = 0;
我还尝试将read_io_threads
和更改write_io_threads
为各种值,以及更改 的数量buffer pool instances
和禁用二进制日志。
是否有任何其他变量可能会有所不同,以尝试加快我错过的速度?
更新 2018-10-17
我设法通过设置在本地(直接在 MySQL 5.7 上)加快查询速度SET @@global.range_optimizer_max_mem_size = 16777216;
。在此之后,查询从 90+ 秒变为 0 秒。
然而,当相同的查询在 MySQL 5.5 上运行并复制到 MySQL 5.7 时,它仍然需要 90 多秒才能运行。
我似乎找到了解决方案。简单的说我设置MySQL 5.5也使用ROW based Replication,使用以下过程:
在此之后,我在 MySQL 5.5 上运行大型查询(立即运行),当它复制到 MySQL 5.7 时,它也立即运行。
因此,MySQL 5.7 处理来自 MySQL 5.5 服务器的基于语句的复制查询似乎存在一些问题。
. . . 但情节变厚了。虽然 MySQL 5.5 数据库声称使用 ROW Based Replication:
SELECT @@GLOBAL.binlog_format;
=ROW
事实上,这似乎有助于复制到 MySQL 5.7,当我抓取最新的二进制日志(一个小时后或大约 10 个二进制日志后)并运行
mysqlbinlog
它们时,我惊讶地发现它们仍然填充了STATEMENTs
. 只有在完全重启数据库后,二进制日志才开始生成新ROW
的格式!!!