Quantcast
Channel: 日々の覚書
Viewing all articles
Browse latest Browse all 581

utf8mb4_0900_ai_ci の速度をどう見るか

$
0
0

TL;DR

  • MySQL 8.0からデフォルトの照合順序が latin1_swedish_ciから utf8mb4_0900_ai_ciになった
  • さすがに latin1をそのまま使っているとは思えないけれど、 utf8mb4だけで見てもデフォルトは utf8mb4_general_ciから utf8mb4_0900_ai_ciに変更になっている
  • 「思ったよりは遅くならない」と見るか、「そんなに遅くなるのか」と見るかは人による気がする

まずは等価比較。
それぞれ10億回繰り返しているので、1回当たりの時間はナノ秒単位になる。
あと、データは保管せずただ比較しているだけなので、単純にCPU勝負のワークロードになる。
mysql80 8> SELECT BENCHMARK(1000000000, '1' = '1' COLLATE utf8mb4_0900_ai_ci) AS utf8mb4_0900_ai_ci; -- 8.0のデフォルト
+--------------------+
| utf8mb4_0900_ai_ci |
+--------------------+
| 0 |
+--------------------+
1 row in set (41.11 sec)

mysql80 8> SELECT BENCHMARK(1000000000, '1' = '1' COLLATE utf8mb4_general_ci) AS utf8mb4_general_ci; -- 5.7までで指定せずにutf8mb4にした時はこれ
+--------------------+
| utf8mb4_general_ci |
+--------------------+
| 0 |
+--------------------+
1 row in set (23.73 sec)

mysql80 8> SELECT BENCHMARK(1000000000, '1' = '1' COLLATE utf8mb4_bin) AS utf8mb4_bin; -- みんなだいすきbin
+-------------+
| utf8mb4_bin |
+-------------+
| 0 |
+-------------+
1 row in set (17.75 sec)

mysql80 8> SELECT BENCHMARK(1000000000, '1' = '1' COLLATE utf8mb4_ja_0900_as_cs) AS utf8mb4_ja_0900_as_cs; -- ハハ != パパ
+-----------------------+
| utf8mb4_ja_0900_as_cs |
+-----------------------+
| 0 |
+-----------------------+
1 row in set (1 min 22.47 sec)

mysql80 8> SET NAMES latin1;
Query OK, 0 rows affected (0.00 sec)

mysql80 8> SELECT BENCHMARK(1000000000, '1' = '1' COLLATE latin1_swedish_ci) AS latin1_swedish_ci; -- 一応latin1も
+-------------------+
| latin1_swedish_ci |
+-------------------+
| 0 |
+-------------------+
1 row in set (17.56 sec)
17nsが82nsになったのを見てどう思うかは人次第。。
しかしこれ、1文字の比較でこれである。文字数が増えれば当然増えていく。
↓単位はすべてns
collate‘1’ = ‘1’‘1a’ = ‘1a’‘yoku0825’ = ‘you0825’‘🍣’ = ‘🍺’
utf8mb4_0900_ai_ci41.1150.34125.5142.21
utf8mb4_general_ci23.7326.8454.0826.46
utf8mb4_bin17.7519.5024.0919.83
utf8mb4_0900_ja_as_cs22.47129.95432.0050.89
latin1_swedish_ci17.5621.6430.0224.20
たかだか8文字の比較で0.4usも持っていかれるのはなかなか…と見るか、それでもus単位だから十分じゃん? と見るか。
更に文字列の比較といえば ORDER BYによるソートももちろん文字列の比較になるので、
mysql80 15> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`num` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`aici` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
`generalci` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`bin` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`ja` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_ja_0900_as_cs DEFAULT NULL,
UNIQUE KEY `num` (`num`)
) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql80 15> SELECT COUNT(*) FROM t1;
+----------+
| COUNT(*) |
+----------+
| 1000000 |
+----------+
1 row in set (0.66 sec)

mysql80 15> SELECT * FROM t1 ORDER BY aici ASC LIMIT 1;
+--------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
| num | aici | generalci | bin | ja
|
+--------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
| 848775 | 0000104cd168386a335ba6bf6e32219d | 0000104cd168386a335ba6bf6e32219d | 0000104cd168386a335ba6bf6e32219d | 0000104cd168386a335ba6bf6e32219d |
+--------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
1 row in set (0.87 sec)

mysql80 15> SELECT * FROM t1 ORDER BY generalci ASC LIMIT 1;
+--------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
| num | aici | generalci | bin | ja
|
+--------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
| 848775 | 0000104cd168386a335ba6bf6e32219d | 0000104cd168386a335ba6bf6e32219d | 0000104cd168386a335ba6bf6e32219d | 0000104cd168386a335ba6bf6e32219d |
+--------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
1 row in set (0.96 sec)

mysql80 15> SELECT * FROM t1 ORDER BY bin ASC LIMIT 1;
+--------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
| num | aici | generalci | bin | ja
|
+--------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
| 848775 | 0000104cd168386a335ba6bf6e32219d | 0000104cd168386a335ba6bf6e32219d | 0000104cd168386a335ba6bf6e32219d | 0000104cd168386a335ba6bf6e32219d |
+--------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
1 row in set (0.92 sec)

mysql80 15> SELECT * FROM t1 ORDER BY ja ASC LIMIT 1;
+--------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
| num | aici | generalci | bin | ja
|
+--------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
| 848775 | 0000104cd168386a335ba6bf6e32219d | 0000104cd168386a335ba6bf6e32219d | 0000104cd168386a335ba6bf6e32219d | 0000104cd168386a335ba6bf6e32219d |
+--------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
1 row in set (1.74 sec)
100万行のクイックソートでこれくらい速度にも違いは出ますわな… utf8mb4_0900_ai_ciはデフォルトだから意識されている気がするけど、 utf8mb4_ja_0900_as_csはやっぱりね…。


インデックスを作る時もやっぱりソートするので



mysql80 16> ALTER TABLE t1 ADD KEY (aici);
Query OK, 0 rows affected (6.05 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql80 16> ALTER TABLE t1 ADD KEY (generalci);
Query OK, 0 rows affected (5.44 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql80 16> ALTER TABLE t1 ADD KEY (bin);
Query OK, 0 rows affected (5.33 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql80 16> ALTER TABLE t1 ADD KEY (ja);
Query OK, 0 rows affected (6.89 sec)
Records: 0 Duplicates: 0 Warnings: 0

こっちはまあ誤差くらいかな…。

ご利用は計画的に。

Viewing all articles
Browse latest Browse all 581

Trending Articles