MySQL 5.7と比べると、8.0の方が性能が良いという噂を簡単な検証で確認してみました。
結論としては、
- 8.0の方がINSERTは早い
- 8.0の方がSELECTも早いけど、正しくインデックス貼られていれば同程度
- UPDATE、DELETEは同程度
という結果でしたー!
なお、サポート期限は以下のようになっています。
MySQLバージョン | MySQL | AWS RDSのMySQL | AWS AuroraのMySQL |
5.7 | 2023年10月31日 | 2023 年 10 月 | 2024 年 10 月 31 日 (Aurora バージョン2) |
8.0 | 2026年4月30日 | 未定 | 未定 (Aurora バージョン3) |
検証条件
- 100万件と200万件のデータに対して、以下のパターンでCRUDの性能を検証
- MySQL5.7インデックスなし
- MySQL8.0インデックスなし
- MySQL5.7インデックスあり
- MySQL8.0インデックスあり
検証結果
100万件の検証結果
MySQL5.7 インデックスなし | MySQL8.0 インデックスなし | MySQL5.7 インデックスあり | MySQL8.0 インデックスあり | 結果比較 | |
100万件インサート | 51.69 sec | 47.43 sec | 58.13 sec | 57.23 sec | 8.0の方が若干早い インデックスありだとインデックス構築分遅くなる |
100万件カウント | 0.49 sec | 0.07 sec | 0.39 sec | 0.07 sec | 8.0の方が早い インデックス貼った方が早い |
1件SELECT | 0.56 sec | 0.54 sec | 0.02 sec | 0.00 sec | 8.0の方が若干早い インデックス貼った方が早い |
1件UPDATE | 0.77 sec | 0.76 sec | 0.01 sec | 0.01 sec | バージョンによる差はほとんどない インデックス貼った方が早い |
1件DELETE | 0.86 sec | 0.87 sec | 0.04 sec | 0.01 sec | バージョンによる差はほとんどない インデックス貼った方が早い |
200万件の検証結果
MySQL5.7 インデックスなし | MySQL8.0 インデックスなし | MySQL5.7 インデックスあり | MySQL8.0 インデックスあり | 結果比較 | |
200万件インサート | 1 min 42.67 sec | 1 min 36.24 sec | 1 min 55.69 sec | 1 min 53.43 sec | 8.0の方が若干早い インデックスありだとインデックス構築分遅くなる |
200万件カウント | 0.84 sec | 0.33 sec | 0.75 sec | 0.15 sec | 8.0の方が早い インデックス貼った方が早い |
1件SELECT | 1.74 sec | 1.04 sec | 0.02 sec | 0.00 sec | 8.0の方が若干早い インデックス貼った方が早い |
1件UPDATE | 1.68 sec | 1.69 sec | 0.02 sec | 0.00 sec | バージョンによる差はほとんどない インデックス貼った方が早い |
1件DELETE | 1.36 sec | 1.82 sec | 0.01 sec | 0.01 sec | バージョンによる差はほとんどない インデックス貼った方が早い |
検証環境
AWS Aurora
インスタンス:db.t3.medium
準備
テーブル作成
以下のテーブルを用意します。インデックスなしテーブルです。
create table user(
id INT,
type INT,
name VARCHAR(255)
);
テストデータ作成用のプロシージャ作成
テストデータはプロシージャーで作成します。
以下の通りデータ作成してくれるようになっています。
- user.id:カウントアップ形式で数値を格納
- user.type:カウントを2で割った余りを格納(あまり意味がないカラムです。)
- user.name:「user_name_{カウント}」の値を格納
-- 区切り文字を「//」に変更する
DELIMITER //
-- make_sample_dataというテストデータ作成用プロシージャーを作成する
create procedure make_sample_data(in i int)
begin
declare count int default 0;
-- 繰り返し
while count < i do
set count = count + 1;
INSERT INTO user VALUES(count, MOD(count,2),CONCAT('usr_name_',count));
end while;
end
//
-- 区切り文字を「;」に戻す
DELIMITER ;
インデックスなし
MySQL 5.7検証
バージョン確認
select version();
+-----------+
| version() |
+-----------+
| 5.7.12 |
+-----------+
1 row in set (0.00 sec)
100万件のパフォーマンス検証
◾️100万件インサート
call make_sample_data(1000000);
Query OK, 1 row affected (51.69 sec)
◾️100万件カウント
select count(*) from user;
+----------+
| count(*) |
+----------+
| 1000000 |
+----------+
1 row in set (0.49 sec)
◾️1件SELECT
select * from user where id = 500000;
+--------+------+-----------------+
| id | type | name |
+--------+------+-----------------+
| 500000 | 0 | usr_name_500000 |
+--------+------+-----------------+
1 row in set (0.56 sec)
◾️1件UPDATE
update user set name = 'name_500001' where id = 500001;
Query OK, 1 row affected (0.77 sec)
Rows matched: 1 Changed: 1 Warnings: 0
◾️1件DELETE
delete from user where id = 500002;
Query OK, 1 row affected (0.86 sec)
200万件のパフォーマンス検証
テーブルを空にする
TRUNCATE TABLE user;
◾️200万件インサート
call make_sample_data(2000000);
Query OK, 1 row affected (1 min 42.67 sec)
◾️200万件カウント
select count(*) from user;
+----------+
| count(*) |
+----------+
| 2000000 |
+----------+
1 row in set (0.84 sec)
◾️1件SELECT
select * from user where id = 1000000;
+---------+------+------------------+
| id | type | name |
+---------+------+------------------+
| 1000000 | 0 | usr_name_1000000 |
+---------+------+------------------+
1 row in set (1.74 sec)
◾️1件UPDATE
update user set name = 'name_1000001' where id = 1000001;
Query OK, 1 row affected (1.68 sec)
Rows matched: 1 Changed: 1 Warnings: 0
◾️1件DELETE
delete from user where id = 1000002;
Query OK, 1 row affected (1.36 sec)
MySQL 8.0検証
バージョン確認
select version();
+-----------+
| version() |
+-----------+
| 8.0.26 |
+-----------+
1 row in set (0.02 sec)
100万件のパフォーマンス検証
テーブルを空にする
TRUNCATE TABLE user;
◾️100万件インサート
call make_sample_data(1000000);
Query OK, 1 row affected (47.43 sec)
◾️100万件カウント
select count(*) from user;
+----------+
| count(*) |
+----------+
| 1000000 |
+----------+
1 row in set (0.07 sec)
◾️1件SELECT
select * from user where id = 500000;
+--------+------+-----------------+
| id | type | name |
+--------+------+-----------------+
| 500000 | 0 | usr_name_500000 |
+--------+------+-----------------+
1 row in set (0.54 sec)
◾️1件UPDATE
update user set name = 'name_500001' where id = 500001;
Query OK, 1 row affected (0.76 sec)
Rows matched: 1 Changed: 1 Warnings: 0
◾️1件DELETE
delete from user where id = 500002;
Query OK, 1 row affected (0.87 sec)
200万件のパフォーマンス検証
テーブルを空にする
TRUNCATE TABLE user;
◾️200万件インサート
call make_sample_data(2000000);
Query OK, 1 row affected (1 min 36.24 sec)
◾️200万件カウント
select count(*) from user;
+----------+
| count(*) |
+----------+
| 2000000 |
+----------+
1 row in set (0.33 sec)
◾️1件SELECT
select * from user where id = 1000000;
+---------+------+------------------+
| id | type | name |
+---------+------+------------------+
| 1000000 | 0 | usr_name_1000000 |
+---------+------+------------------+
1 row in set (1.04 sec)
◾️1件UPDATE
update user set name = 'name_1000001' where id = 1000001;
Query OK, 1 row affected (1.69 sec)
Rows matched: 1 Changed: 1 Warnings: 0
◾️1件DELETE
delete from user where id = 1000002;
Query OK, 1 row affected (1.82 sec)
インデックスあり
user.idにインデックスをはる
alter table user add index id_index (id);
MySQL 5.7検証
100万件のパフォーマンス検証
テーブルを空にする
TRUNCATE TABLE user;
◾️100万件インサート
call make_sample_data(1000000);
Query OK, 1 row affected (58.13 sec)
◾️100万件カウント
select count(*) from user;
+----------+
| count(*) |
+----------+
| 1000000 |
+----------+
1 row in set (0.39 sec)
◾️1件SELECT
select * from user where id = 500000;
+--------+------+-----------------+
| id | type | name |
+--------+------+-----------------+
| 500000 | 0 | usr_name_500000 |
+--------+------+-----------------+
1 row in set (0.00 sec)
◾️1件UPDATE
update user set name = 'name_500001' where id = 500001;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
◾️1件DELETE
delete from user where id = 500002;
Query OK, 1 row affected (0.04 sec)
200万件のパフォーマンス検証
テーブルを空にする
TRUNCATE TABLE user;
◾️200万件インサート
call make_sample_data(2000000);
Query OK, 1 row affected (1 min 55.69 sec)
◾️200万件カウント
select count(*) from user;
+----------+
| count(*) |
+----------+
| 2000000 |
+----------+
1 row in set (0.75 sec)
◾️1件SELECT
select * from user where id = 1000000;
+---------+------+------------------+
| id | type | name |
+---------+------+------------------+
| 1000000 | 0 | usr_name_1000000 |
+---------+------+------------------+
1 row in set (0.02 sec)
◾️1件UPDATE
update user set name = 'name_1000001' where id = 1000001;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
◾️1件DELETE
delete from user where id = 1000002;
Query OK, 1 row affected (0.01 sec)
MySQL 8.0検証
100万件のパフォーマンス検証
テーブルを空にする
TRUNCATE TABLE user;
◾️100万件インサート
call make_sample_data(1000000);
Query OK, 1 row affected (57.23 sec)
◾️100万件カウント
select count(*) from user;
+----------+
| count(*) |
+----------+
| 1000000 |
+----------+
1 row in set (0.07 sec)
◾️1件SELECT
select * from user where id = 500000;
+--------+------+-----------------+
| id | type | name |
+--------+------+-----------------+
| 500000 | 0 | usr_name_500000 |
+--------+------+-----------------+
1 row in set (0.00 sec)
◾️1件UPDATE
update user set name = 'name_500001' where id = 500001;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
◾️1件DELETE
delete from user where id = 500002;
Query OK, 1 row affected (0.01 sec)
200万件のパフォーマンス検証
テーブルを空にする
TRUNCATE TABLE user;
◾️200万件インサート
call make_sample_data(2000000);
Query OK, 1 row affected (1 min 53.43 sec)
◾️200万件カウント
select count(*) from user;
+----------+
| count(*) |
+----------+
| 2000000 |
+----------+
1 row in set (0.15 sec)
◾️1件SELECT
select * from user where id = 1000000;
+---------+------+------------------+
| id | type | name |
+---------+------+------------------+
| 1000000 | 0 | usr_name_1000000 |
+---------+------+------------------+
1 row in set (0.00 sec)
◾️1件UPDATE
update user set name = 'name_1000001' where id = 1000001;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
◾️1件DELETE
delete from user where id = 1000002;
Query OK, 1 row affected (0.01 sec)
普通の子に会える
まとめ
MySQL5.7と8.0のパフォーマンスを検証してみましたー!
結果としては
- 8.0の方がINSERTは早い
- 8.0の方がSELECTも早いけど、正しくインデックス貼られていれば同程度
- UPDATE、DELETEは同程度
です!
UPDATEは更新カラムにインデックス貼られてるか否かで結果が変わってくるかもと思いますが、簡単な検証結果ということで!
MySQLのインデックスを貼ったカラムを更新するとインデックスサイズが肥大化するよ!という記事もありますので、よろしければ!