クエリを実行するときのデータベースの仕事の1つは、クエリ自体を実行するための最良の方法を計画することです。ほとんどの場合、MariaDB(およびMySQL)は最適化の優れた仕事をしますが、結合数が多い複雑なクエリの場合、実際にクエリを実行するのではなく、デフォルトでクエリの最適化に時間がかかりすぎる可能性があります。
たとえば、16個のJOINステートメントを使用したWordPressベースのクエリでは、実行時間がほぼ4分でした。 たった5000行です。クエリ(実際にはクエリを実行しない)でEXPLAINを実行すると、ほぼ同じ結果になります。つまり、遅延は過度の最適化です データやクエリ自体ではありません。
これはoptimizer_search_depthによるものです 設定。デフォルトは62です。この数値を5の深さに減らすことにより、EXPLAIN時間は0.052秒に短縮され、クエリ自体は6秒未満に短縮されました。
この特定のクエリでは、結果がほぼ 3900%遅くなることを意味しました サーバーのデフォルトで!
- MariaDBシェルを使用してクエリを実行し、クエリ中にMariaDBが何であるかを確認します。
show full processlist
; - 「統計」の状態のクエリが長時間表示される場合は、この最適化が適用できる可能性があります。例えば:
- 現在のoptimizer_search_depthを確認します に設定されています:
show variables like "optimizer_search_depth";
たとえば、次のように表示されます。
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| optimizer_search_depth | 62 |
+------------------------+-------+
- これは、サーバーがまだシステムデフォルトを実行していることを示します。
- optimizer_search_depthをゼロに設定して、深さを自動最適化するようにサーバーを設定してテストします。
SET SESSION optimizer_search_depth = 0;
- 遅いSQLクエリを再実行して、問題が解決したことを確認します。
- 更新された設定が機能する場合は、/ etc / my.confを編集し、 [msqld] で明示的に設定して、永続的に設定します。 セクション:
optimizer_search_depth=0
- MariaDBを再起動して適用します:
systemctl restart mariadb
ヒント
データ構造が非常に制御されていることがわかっている場合は、optimizer_search_depthを明示的に設定してみることができます。 をさらに減らすために、特定の値(たとえば、5)に変更します。ただし、明示的な設定は必ずしもすべての場合に高速であるとは限らないため、徹底的にテストしてください。
この問題が発生している仮想プライベートサーバーを使用しているConetixのお客様の場合、これが原因であることを確認し、追加費用なしで修正することができます。さらにサポートが必要な場合は、サポートチームにお問い合わせください。
https://www.percona.com/blog/2012/04/20/joining-many-tables-in-mysql-optimizer_search_depth/
https://mariadb.com/resources/blog/setting-optimizer-search-depth-in-mysql/