どうやらMySQL 8.0がGAになったようですが、
MySQL :: MySQL 8.0 Release Notes :: Changes in MySQL 8.0.11 (2018-04-19, General Availability)
Qiitaに書くほどのことでもないので、こちらでくだらない小ネタを1つ。
先日、Qiitaにこれ
を書いたのと、みんな大好き世界のyoku0825さんが、これ
を書かれたので、あらためてMySQL 8.0のリファレンスマニュアルを読み返したところ、
ここ
MySQL :: MySQL 8.0 Reference Manual :: 12.13 Encryption and Compression Functions
と、ここ
MySQL :: MySQL 8.0 Reference Manual :: 25.9 Performance Schema Statement Digests and Sampling
で、正規化したSQLの表現が若干違うのが気になりました(後者にはカラム名等のバッククォートがない)。
実際に確かめてみたところ、前者が正しい表現でした。
で、ついでに「どこまで正規化されるのか?」が気になったので、軽く試してみました。
バッククォートと空白、キーワード/予約語の大文字小文字は、
mysql> SELECT STATEMENT_DIGEST('SELECT `hoge1`, `hoge2` FROM `hoge`.`fuga`');
+------------------------------------------------------------------+
| STATEMENT_DIGEST('SELECT `hoge1`, `hoge2` FROM `hoge`.`fuga`') |
+------------------------------------------------------------------+
| 1b1547c6f30f8a648296cbac9c40857014fab13917c7e6aaccb915eabb9194e3 |
+------------------------------------------------------------------+
1 row in set (0.00 sec)mysql> SELECT STATEMENT_DIGEST('SELECT hoge1, hoge2 FROM hoge.fuga');
+------------------------------------------------------------------+
| STATEMENT_DIGEST('SELECT hoge1, hoge2 FROM hoge.fuga') |
+------------------------------------------------------------------+
| 1b1547c6f30f8a648296cbac9c40857014fab13917c7e6aaccb915eabb9194e3 |
+------------------------------------------------------------------+
1 row in set (0.00 sec)mysql> SELECT STATEMENT_DIGEST('SELECT hoge1, hoge2 FROM hoge.fuga');
+------------------------------------------------------------------+
| STATEMENT_DIGEST('SELECT hoge1, hoge2 FROM hoge.fuga') |
+------------------------------------------------------------------+
| 1b1547c6f30f8a648296cbac9c40857014fab13917c7e6aaccb915eabb9194e3 |
+------------------------------------------------------------------+
1 row in set (0.00 sec)mysql> SELECT STATEMENT_DIGEST('select hoge1, hoge2 from hoge.fuga');
+------------------------------------------------------------------+
| STATEMENT_DIGEST('select hoge1, hoge2 from hoge.fuga') |
+------------------------------------------------------------------+
| 1b1547c6f30f8a648296cbac9c40857014fab13917c7e6aaccb915eabb9194e3 |
+------------------------------------------------------------------+
1 row in set (0.00 sec)
こんな感じで同じものとしてうまく正規化されました(ダイジェスト値が同じ)。
mysql> SELECT STATEMENT_DIGEST('SELECT HOGE1, HOGE2 FROM HOGE.FUGA');
+------------------------------------------------------------------+
| STATEMENT_DIGEST('SELECT HOGE1, HOGE2 FROM HOGE.FUGA') |
+------------------------------------------------------------------+
| 6c952560d06129f0ec76ebfb8e2180af28821831d1dd75c7fc3bf4f03a85dc41 |
+------------------------------------------------------------------+
1 row in set (0.00 sec)
カラム名については、大文字・小文字の区別があるので別のダイジェスト値になります。
※「lower_case_table_names
」の設定に関わらず、の模様。
文字列(定数)のクォートの違いについては、
mysql> SELECT STATEMENT_DIGEST("SELECT 'aaa'");
+------------------------------------------------------------------+
| STATEMENT_DIGEST("SELECT 'aaa'") |
+------------------------------------------------------------------+
| d1b44b0c19af710b5a679907e284acd2ddc285201794bc69a2389d77baedddae |
+------------------------------------------------------------------+
1 row in set (0.00 sec)mysql> SELECT STATEMENT_DIGEST('SELECT "aaa"');
+------------------------------------------------------------------+
| STATEMENT_DIGEST('SELECT "aaa"') |
+------------------------------------------------------------------+
| d1b44b0c19af710b5a679907e284acd2ddc285201794bc69a2389d77baedddae |
+------------------------------------------------------------------+
1 row in set (0.00 sec)
という感じで、表記が揺れても同じダイジェスト値になりました。
…しかし、クエリキャッシュが活用されていた頃にはキャッシュされたクエリが正規化されなかったのに、5.6→5.7→8.0と、クエリキャッシュが非推奨→廃止になる一方で、SQLの正規化機能が向上する(パフォーマンススキーマでMD5正規化対応→SHA-256対応→関数で正規化SQLのダイジェストやテキストも取り出せる)というのは、なんだか皮肉な感じですね。
※正確には、クエリキャッシュでは定数を「?」に置き換えてはいけないので、正規化の範囲が違いますが。