MySQL道普請便り

第248回知っておくと得するかもしれないMySQLの組み込み関数

MySQLでは標準でさまざまな組み込み関数を用意しています。これらはステートメントの以下のようなポイントで使用できます。

  • SELECTステートメントのORDER BYやHAVING句
  • SELECTステートメントの取得するリスト内
  • SELECT、DELETEやUPDATEステートメントのWHERE句

今回は、その中でも「知っておくと得する」可能性のある関数をいくつかピックアップしてご紹介します。

BENCHMARK()関数

はじめにBENCHMARK()関数です。BENCHMARK()関数では、特定の式や関数の実行速度を測定することができます。ステートメントの実行にどのくらいの時間を要したかを表示する行を出力します。構文はBENCHMARK(count,expr)で、exprをcountの回数だけ繰り返し実行します。

mysqlコマンドラインクライアントでMySQLへアクセスして、BENCHMARK()関数を実行してみましょう。

mysql>  SELECT BENCHMARK(1000000,HEX(100*1000));
+-----------------------------------+
| BENCHMARK(1000000,HEX(100*+1000)) |
+-----------------------------------+
|                                 0 |
+-----------------------------------+
1 row in set (0.03 sec)

この例ではHEX(100*1000)という式を100万回試行したところ、0.03 sec時間がかかったことがわかります。報告される時間は、クライアント側での経過時間を示しており、サーバー側でのCPU時間ではありません。サーバーの負荷状況を正確に理解するためには、BENCHMARK()関数を複数回実行して結果を分析する必要があります。

また、BENCHMARK()を用いて異なるサーバー間の速度の違いを比較することができます。

注意として、評価する式にクエリを含めることは可能ですが、複数のカラムや複数の行が返されるクエリはエラーとなります。その際はサブクエリにして単一行および単一のカラムとなるように工夫する必要があります。

例:複数のカラム返されるクエリによるエラー
mysql> SELECT BENCHMARK(10000,(SELECT 1,2));
ERROR 1241 (21000): Operand should contain 1 column(s) 
例:サブクエリに変更
mysql>  SELECT BENCHMARK(10000,(SELECT 1 FROM (SELECT 1,2) a LIMIT 1));
+--------------------------------------------------------+
| BENCHMARK(10000,(SELECT COUNT(*) FROM (SELECT 1,2) a)) |
+--------------------------------------------------------+
|                                                      0 |
+--------------------------------------------------------+
1 row in set (0.01 sec)

BENCHMARK()関数では、特定のクエリや計算の効率を評価し、最適化の必要性を判断することができます。たとえば、同じクエリを異なるデータベース設定やインデックス構成で実行することで、パフォーマンスのボトルネックを特定する手助けになります。また、結果の分析を通じて、サーバーのリプレイスやバージョンアップ、設定変更がどの程度の効果を持つかを事前に予測することも可能です。

ROW_COUNT()関数

ROW_COUNT()関数は、SELECT以外のDMLステートメント(UPDATE、INSERT、DELETE)にて影響を受けた行数を返します。次の例では、INSERTステートメントにて3行挿入したあとに、この関数を実行して影響を受けた行数として3が出力されているのがわかります。

mysql> insert into t0(col1) values (1),(2),(3);
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           3 |
+-------------+
1 row in set (0.00 sec)

この関数は影響を受けた(実際に更新があった)行を出力します。次の例では前述のINSERT文で追加した行を更新します。元々col1の値が3であったものはROW_COUNT()でカウントされず、結果として2が出力されます。このように、変更がなかった行(すでに指定された値だった行)はカウントされません。

mysql>  UPDATE t0 SET col1=3;
Query OK, 2 rows affected (0.00 sec)
Rows matched: 3  Changed: 2  Warnings: 0

mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           2 |
+-------------+
1 row in set (0.00 sec)

STATEMENT_DIGEST_TEXT()関数

STATEMENT_DIGEST_TEXT()関数はSQLステートメントを文字列として指定すると、正規化された文字列(ステートメントダイジェスト)を返します。正規化ではリテラル値の削除や空白の正規化などさまざまな処理が行われ、SQLステートメントが抽象化されます。

mysql> SELECT STATEMENT_DIGEST_TEXT('SELECT * FROM t0 WHERE col1 = 10000') as text;
+-------------------------------------+
| text                                |
+-------------------------------------+
| SELECT * FROM `t0` WHERE `col1` = ? |
+-------------------------------------+

これにより、正規化した形式で類似のクエリをグループ化するなどの応用が可能になります。また、出力結果はperformance_schemaのevents_statements_summary_by_digestテーブルのDIGEST_TEXTカラムの値と同等のものです。max_digest_length変数にて正規化されたステートメントダイジェストを計算するために、これらの関数で使用できる最大バイト数を指定できます。デフォルトは1024バイトです。

VALIDATE_PASSWORD_STRENGTH()関数

VALIDATE_PASSWORD_STRENGTH()関数は、プレーンテキストパスワードを表す引数を指定すると、パスワードの強さを示す整数を戻します。 戻り値は、0(弱)から100(強)までの範囲内です。このパスワード評価はvalidate_passwordコンポーネントによって実行されるため、事前にこのコンポーネントのインストールが必要です。

validate_passwordコンポーネントのインストール
mysql> INSTALL COMPONENT 'file://component_validate_password';
Query OK, 0 rows affected (0.28 sec)
VALIDATE_PASSWORD_STRENGTH()関数の実行例
mysql> SELECT VALIDATE_PASSWORD_STRENGTH('AbCdEfG');
+---------------------------------------+
| VALIDATE_PASSWORD_STRENGTH('AbCdEfG') |
+---------------------------------------+
|                                    25 |
+---------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT VALIDATE_PASSWORD_STRENGTH('Ab!dE$gH*JK^&!lO1');
+-------------------------------------------------+
| VALIDATE_PASSWORD_STRENGTH('Ab!dE$gH*JK^&!lO1') |
+-------------------------------------------------+
|                                             100 |
+-------------------------------------------------+
1 row in set (0.00 sec)

パスワードの戻り値は、以下のロジックに従い導出されます。

スコア判定基準
条件 戻り値
長さが4文字以下 0
長さが4文字以上、validate_password.length未満 25
validate_password.policy=LOW を満たす 50
validate_password.policy=MEDIUM を満たす 75
validate_password.policy=STRONG を満たす 100

詳細は、第228回 MySQLのvalidate_passwordコンポーネントでパスワードセキュリティを強化しよう ですでに紹介していますので、ご参照ください。

まとめ

今回は、知っておくと得するかもしれないMySQLの組み込み関数として、MySQLの組み込み関数の中から以下の4つの関数を紹介しました。

  • BENCHMARK():パフォーマンス測定
  • ROW_COUNT():DMLによる影響行数取得
  • STATEMENT_DIGEST_TEXT():SQLの正規化
  • VALIDATE_PASSWORD_STRENGTH():パスワード強度の評価

この他にも、MySQLには多種多様な関数が用意されています。興味のある方は公式ドキュメント 14.1 Built-In Function and Operator Reference を参照してみてください。

おすすめ記事

記事・ニュース一覧