MySQL クエリの最適化には、解析、前処理、最適化という 3 つのステップが必要です。これらのプロセスのいずれかの過程でエラーが発生する可能性があります。この記事では、エラー処理について詳しく説明しません。ただし、MySQL がクエリを実行する方法を理解して、より優れたクエリを作成できるようにするのに役立ちます。 パーサーとプリプロセッサ最初に、MySQL のパーサーはクエリを一連の命令に分割し、それらから「解析ツリー」を構築します。パーサーは、MySQL の SQL 構文を使用してクエリ ステートメントを変換および検証します。たとえば、パーサーはクエリ内の命令が有効で正しい順序であることを確認し、文字列内の引用符が一致しないなどのエラーをチェックします。 プリプロセッサは、構築された解析ツリーをチェックして、パーサーが処理できない意味情報がないかどうかを確認します。たとえば、テーブルと列の存在がチェックされ、フィールド名とエイリアスが処理されて、列参照が明確であることが保証されます。次に、プリプロセッサが権限をチェックします。これは通常、かなり高速です (サーバーに多数の権限が設定されていない場合)。 クエリオプティマイザーパーサーとプリプロセッサを通過した後、解析ツリーは有効であると判断され、オプティマイザーによって処理され、最終的にクエリ プランに変換されます。多くの場合、同じ結果を生成するクエリを実行する方法は多数あり、オプティマイザーの役割は最適なオプションを見つけることです。 MySQL はコスト見積もりに基づくオプティマイザーを使用します。つまり、複数の実行プランのコストを予測し、コストが最も低いものを選択します。元の単位コストはランダムな 4KB データ ページの読み取りでしたが、現在はより複雑になり、WHERE 比較条件を実行するコストも含まれるようになりました。 Last_query_cost セッション変数を表示することで、クエリ オプティマイザーによるクエリ ステートメントのコストの見積もりを表示できます。 sakila.film_actor から SQL_NO_CACHE COUNT(*) を選択します。 'Last_query_cost' のようなステータスを表示します。 表示される Last_query_cost は、クエリを完了するために、対応する数のランダム データ ページ アクセスを実行する必要があることをオプティマイザーが見積もっていることを意味します。これは以下の統計的推定に基づいています。
オプティマイザーはキャッシュの推定を考慮せず、結果が毎回ディスク I/O から読み取られると想定します。オプティマイザーは、次の理由により、必ずしも最適な実行プランを選択するとは限りません。
MySQL クエリ オプティマイザーは、多くの最適化方法を使用してクエリ ステートメントをクエリ実行プランに変換する非常に複雑な部分です。通常、最適化には静的最適化と動的最適化の 2 種類があります。静的最適化は、解析ツリーを検査するだけで実行できます。たとえば、オプティマイザーは数学的な演算ルールを通じて WHERE 条件を方程式に変換できます。静的最適化は、WHERE 条件内の定数値などの特定の値とは関係ありません。これらは一度実行され、異なる値でクエリが再度実行された場合でも有効なままです。これは「コンパイル時の最適化」として理解できます。 対照的に、動的最適化はコンテキストに固有であり、さまざまな要因に依存します。たとえば、WHERE 条件の値や、インデックス内の対応するデータ行の数などです。このプロセスはクエリごとに再推定する必要があり、「実行時の最適化」として理解できます。 MySQL の一般的な最適化方法を以下に示します。
EXPLAIN SELECT film.film_id、film_actor.actor_id sakila.filmより INNER JOIN sakila.film_actor USING(film_id) ここで、film.film_id = 1; MySQL はこのクエリを 2 つのステップに分割するため、分析結果には 2 つの行が含まれます。最初のステップは、フィルム テーブル内の対応するデータ行を見つけることです。クエリは主キー film_id に基づいているため、MySQL はデータが 1 行しかないことを認識します。 したがって、このときのクエリ解析結果のrefは定数となります。 2 番目のステップでは、MySQL は film_id を既知の値として扱うため、film_actor のクエリの ref も定数になります。その他の同様のシナリオとしては、WHERE、USING、または ON 条件の制約が等式である場合が挙げられます。この例では、MySQL は USING 条件の film_id がすべてのクエリで同じ値であり、この値は WHERE 条件の film_id と同じでなければならないことを認識しています。
EXPLAIN SELECT film.film_id FROM sakila.film WHERE film_id=1; 分析結果の「追加」フィールドに、「const テーブルを読み取った後に不可能な WHERE が検出されました」と表示されます。早期終了が発生する可能性があるその他の状況としては、次のようなものがあります。 フィルム.フィルムIDを選択 sakila.filmより 左外部結合 sakila.film_actor USING (film_id) sakila.film_actor.film_id が NULL の場合; このクエリでは、俳優が出演している映画は除外されます。各映画には複数の俳優が登場する場合がありますが、俳優が見つかると、MySQL は現在の映画の処理を停止し、次の映画に進みます。 DISTINCT と NOT EXISTS でも同様の状況が発生します。
フィルム.フィルムIDを選択 sakila.filmより INNER JOIN sakila.film_actor USING(film_id) ここで、film.film_id > 500; MySQL は、WHERE 制約が film テーブルだけでなく film_actor テーブルにも適用されることを認識します。ただし、この最適化効果は他のデータベースでは達成されない可能性があります。
実際、MySQL では上記に挙げたもの以外にも多くの最適化方法が使用されており、ここですべてを列挙することは不可能です。 MySQL のオプティマイザーの複雑さと、それがどれほどスマートであるかを思い出してください。したがって、MySQL オプティマイザに改善の余地がなくなるまでクエリ ステートメントを無期限に最適化するのではなく、オプティマイザがその役割を果たせるようにする必要があります。もちろん、MySQL のオプティマイザーは非常にスマートですが、必ずしも最良の結果が得られるとは限りません。最良の結果がわかっていても、MySQL がそれを知らない場合もあります。この場合、クエリ ステートメントを最適化して MySQL が最適化作業を完了できるようにすることができますが、クエリ ヒントを追加したり、クエリを書き直したり、データ テーブルの設計を変更したり、インデックスを追加したりする必要がある場合もあります。 上記は、MySQL クエリ最適化プロセスを理解するための詳細です。MySQL クエリ最適化の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
コードをコピーコードは次のとおりです。 <スタイル> .fileInputContain...
目次概要関数シグネチャオプションパラメータ非厳密モード例外処理実用要約する概要ご存知のとおり、ES6...
Baiduクラウドディスク:リンク: https://pan.baidu.com/s/1hv5rUW...
序文node.js でサーバーを作成するのは非常に簡単です。小さいながらも完全な Web サーバーを...
CSS3 アニメーション トランジションを使用して、リンクの上にマウスを移動すると小さなポップアップ...
目次序文1. 取引の基本原則の簡単な分析原子性:持続性分離:一貫性: 2. 分離レベルの基本原理の分...
1. プリコンパイルの利点私たちは皆、プリコンパイル機能を備えた JDBC の PreparedSt...
img 画像タグに alt 属性を追加しますか?画像 img タグの alt 属性を見落とすことはよ...
目次1. グループクエリの概略図2. groupbyキーワード構文の詳細な説明3. 簡単なグループク...
WeChatアプレットのログインインターフェースは参考までに実装されています。具体的な内容は次のとお...
HTMLカラーブロックを使用してデータを動的に表示する <スタイル タイプ="te...
1 QPS 計算 (1 秒あたりのクエリ数) MyISAMエンジンベースのDBの場合 MySQL&g...
序文MySQL の rowid の概念については聞いたことがあるかもしれませんが、テストや実践が難し...
Docker コンテナはサービスを提供し、ポート 8888 をリッスンします。外部からアクセスできる...
目次1. 従来のコレクションに対するフィルター、マップ、および削減処理方法2. 再帰処理3. for...