MySQL 8.0最重要的特性是对NoSQL的支持更加完善, 官网上用太极图来表达了NoSQL比重
官方号称可以干掉其它的NoSQL数据库了
8.0 使用json-partial-updates
特性来提高json的更新效率, 也就是只更新指定的json字段, 其它字段不变.
而5.7版本, 会更新整个json.
经过我的测试, 当json比较小时, 5.7还快一点, 只有当json特别特别长时, 才有效果. 因为数据量小时, 写磁盘的速度都是一样的. 但是固态磁盘我没试过.
8.0和5.7的默认系统参数配置不一样
参数 | 说明 | 8.0 | 5.7 |
---|---|---|---|
have_query_cache | 缓存query结果, 提高效率 | 不再支持query cache了, 以后开发者自求多福吧, client自己处理cache问题 |
支持 |
innodb_flush_log_at_trx_commit | 每次提交都写日志, 影响效率 | 默认开启 | 默认关闭 |
innodb_flush_neighbors | 对于普通硬盘, 开启此参数, 可提交IO效率 |
默认关闭 | 默认开启 |
bin-log | 开启 | 关闭 |
https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit
https://dev.mysql.com/doc/refman/8.0/en/replication-options-binary-log.html
准备两台一模一样的主机, 一个安装8.0, 一个安装5.7最新版 (至少需要5.7.8)
将这两个mysql的参数设置成一样的.
vim /etc/my.cnf
在末尾加上skip-log-bin
, 或者disable-log-bin
service mysqld restart
本人准备的是两台1核的阿里云主机
创建表
set global innodb_flush_neighbors = 0;
set global innodb_flush_log_at_trx_commit = 1;
set global query_cache_size = 0;
两个数据库都执行以下语句
CREATE DATABASE IF NOT EXISTS `test`;
use test;
CREATE TABLE `test`.`t` (`id` INT,`c` JSON, k2 int as (c->'$.k2') PRIMARY KEY (`id`));
这里给json中的k2
字段添加了一个虚拟列, 方便操作
INSERT INTO t (id, c) VALUES(1, JSON_OBJECT("k1", REPEAT('x', 1000*100), "k2", 0));
这里使用REPEAT('x', 1000*100)
来创建一个很大很大的字符串. 如果字符串太短的话, 测不出效果
mysqlslap -uroot -pqW123456! \
--create-schema=test \
--commit=1 --concurrency=1 --iterations=1 \
--query='UPDATE `t` SET `c` = JSON_SET(`c` ,"$.k2" , k2 + 1) WHERE `id` = 1;' \
--engine=innodb --number-of-queries=5000
mysqlslap: [Warning] Using a password on the command line interface can be insecure.
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 11.355 seconds
Minimum number of seconds to run all queries: 11.355 seconds
Maximum number of seconds to run all queries: 11.355 seconds
Number of clients running queries: 1
Average number of queries per client: 5000
mysqlslap -uroot -p123456 \
--create-schema=test \
--commit=1 --concurrency=1 --iterations=1 \
--query='UPDATE `t` SET `c` = JSON_SET(`c` ,"$.k2" , k2 + 1) WHERE `id` = 1;' \
--engine=innodb --number-of-queries=5000
mysqlslap: [Warning] Using a password on the command line interface can be insecure.
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 18.978 seconds
Minimum number of seconds to run all queries: 18.978 seconds
Maximum number of seconds to run all queries: 18.978 seconds
Number of clients running queries: 1
Average number of queries per client: 5000