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 の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
目次問題の説明シナリオインターフェースリターンフロントエンドメニューの定義vuex のメソッド問題原...
追加するdocker run -it -name test -d nginx:latest /bin...
目次1. カウントデータが失われる解決2. 明確なデータ損失3.データ損失を選択解決4. Nullポ...
目次1. DHCP サービス (動的ホスト構成プロトコル) 1. 背景2. 概要3. 利点4.DHC...
目次導入使用シナリオソースコード分析要約する導入Vue は、コンポーネントをステートレスかつインスタ...
HTML と CSS で、ボタンの色を設定したいとします。 目的の効果は得られますが、プロセスはかな...
方法1: SET PASSWORDコマンドを使用する MySQL -u ルート mysql> ...
目次1. リソースのダウンロード2. ソフトウェアを解凍する2.1 場所を選択する2.2 名前を変更...
問題を見つける最近MySQLをMySQL 5.7にアップグレードした後、次のようなクエリでグループ化...
使用される Docker イメージが増えるにつれて、イメージを保存する場所、つまりウェアハウスが必要...
私が学習していたときに使用していたバージョンは比較的新しいものであり、インターネット上のチュートリア...
現在、ほぼすべての大規模な Web サイトとアプリケーションは分散方式で展開されています。分散シナリ...
目次1. ダウンロード2. 展開1.Nginxのデプロイメント2. ModSecurityの展開3....
大きな箱の中に写真があります。マウスをその上に置くと、半透明のマスク レイヤーが表示されます。マウス...
CSS は、スクロールを許可しながらスクロール バーを非表示にするために Overflow を設定し...