一般的な提案は、WHERE 条件のインデックスを作成することですが、これは実際には一方的です。インデックスは、WHERE 条件だけでなく、すべてのクエリに対して設計する必要があります。インデックスはデータ行を効率的に見つけるのに役立ちますが、MySQL ではインデックスを使用して、データ行をまったく読み取ることなく列データを取得することもできます。結局のところ、インデックスのリーフ ノードには、インデックスに対応する値が含まれます。必要なデータを取得するにはインデックスを読み取るだけでよいのに、なぜ行を読み取る必要があるのでしょうか?インデックスにクエリのすべてのデータが含まれている場合、そのインデックスはカバーリング インデックスと呼ばれます。 カバーリングインデックスは非常に強力なツールとなり、パフォーマンスを大幅に向上させることができます。データを読み取る必要はなく、インデックスのみを読み取る必要がある場合を考えてみましょう。
いずれの場合も、最も典型的なのは、インデックス付き列のみを含むクエリのコストが、データ行を検索するコストよりもはるかに低くなることです。クラスター化インデックスは単なるインデックスの種類ではないことに注意することが重要です。クラスター化インデックスには、インデックスが付けられたデータ列に対応する値を格納する必要があります。ハッシュ、空間、およびフルテキスト インデックスにはこれらの値は保存されないため、MySQL ではクエリをカバーするためにバイナリ ツリーのみを使用できます。さらに、異なるストレージ エンジンは異なる方法でカバーリング インデックスを実装しており、すべてのストレージ エンジンがカバーリング インデックスをサポートしているわけではありません (たとえば、Memory ストレージ エンジンは現在これをサポートしていません)。 クエリ内のインデックスがカバーリング インデックスを使用していることを確認すると、Explain ステートメントの使用時に [Extra] 列に [Using index] が表示されます。たとえば、store_goods テーブルには複数列のインデックス (shop_id、goods_category_id1) があります。 MySQL は、クエリが次の 2 つの列のデータのみを返す場合にインデックスを使用できます。 EXPLAIN SELECT `goods_category_id1`,`shop_id` FROM `store_goods` WHERE 1 インデックス クエリをカバーすると、場合によってはこのような最適化が無効になることがあります。 MySQL クエリ オプティマイザーは、クエリを実行するときにインデックスがクエリをカバーするかどうかを判断します。インデックスが WHERE 条件をカバーしているが、クエリ全体をカバーしていないとします。評価の結果、カバーリング インデックスを使用しないことが決定された場合、MySQL 5.5 以前のバージョンでは、データが不要であってもデータ行を直接フェッチし、それらをフィルター処理します。 なぜこのようなことが起こるのか、そしてこの問題を解決するためにクエリを書き直す方法を見てみましょう。最初のクエリは次のようになります。 EXPLAIN SELECT * FROM products WHERE actor='SEAN CARREY' AND title like '%APOLLO%' この時点での結果は、カバー インデックスではなく通常のインデックスが使用されることです。その理由は次のとおりです。
インデックスを巧みに組み合わせてクエリを書き換えることで、これを実現する方法があります。インデックスを (artist、title、prod_id) に拡張し、クエリを次のように書き換えることができます。 説明選択 * 製品から 参加する ( prod_idを選択 製品から 俳優が「ショーン・キャリー」でタイトルが「%アポロ%」の場合 ) AS t1 ON (t1.prod_id=products.prod_id) 列へのアクセスを遅らせるため、これを「遅延結合」と呼びます。クエリの最初のフェーズでは、サブクエリ内で一致する行が見つかると、MySQL はカバー インデックスを使用します。クエリ全体でカバーされているわけではありませんが、何もないよりはましです。 この最適化の有効性は、WHERE 条件で見つかったデータの行数によって異なります。製品テーブルに数百万行のデータが含まれていると仮定します。合計 100 万行のデータを使用して、これら 2 つのクエリのパフォーマンスを比較できます。
比較結果を次の表に示します。
結果は次のように説明されます。
ほとんどのストレージ エンジンでは、インデックスはインデックスの一部である列へのアクセスのみをカバーできます。ただし、InnoDB は実際にはさらに最適化を行います。 InnoDB のセカンダリ インデックスがリーフ ノードに主キーの値を格納すると考えてください。つまり、InnoDB のセカンダリ インデックスには、InnoDB がカバー インデックスを使用するのに役立つ追加の列が実際に存在します。 たとえば、sakila.actor テーブルは InnoDB を使用し、last_name にインデックスがあるため、この列がインデックスの一部ではない場合でも、このインデックスは主キー actor_id に基づくクエリをカバーできます。 EXPLAIN SELECT 俳優ID、姓 sakila.actor から last_name = 'HOPPER' 上記はMySQLカバーリングインデックスの利点の詳細な内容です。MySQLカバーリングインデックスの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<<: JavaScriptはXiaomi Mall公式サイトの完全なページ実装プロセスを模倣します
>>: border-image を使用してテキストバブルの境界線を実装する方法のサンプルコード
今日ご紹介したいのは、ネイティブ JS を使用してプログレス バーをドラッグし、要素の透明度を変更す...
この記事では、例を使用して、MySQL の計画されたタスクとイベントのスケジュールについて説明します...
目次1. イベントとは何ですか? 2. 「イベント」機能を有効にする1. 機能が有効になっているかど...
昨年末、Thinkpad T450 のデュアルシステムの opensuse を Manjaro に置...
MySQLをアンインストールする1. コントロールパネルで、MySQLのすべてのコンポーネントをア...
こんなことがありました。今日はGitHubで遊んでいました。最初はログインせずにいくつかのページを閲...
この記事では、ディープラーニングフレームワーク keras を使用して、SQL インジェクションの特...
数日前、ある要件に取り組んでいたとき、MySQL で重複レコードをクリーンアップする必要がありました...
これは私が Vue フレームワークを独学していたときに真似したウェブサイトです。いくつかの都市の天気...
目次序文1. 従来のVueコンポーネント1. メインコンポーネントコード: 2. 使用方法3. 成果...
目次1. 問題のあるSQL文たとえば、次の図のような質問をした人がいました。 問題は次のように要約で...
履歴書コード: XML/HTML コードコンテンツをクリップボードにコピー<!DOCTYPE ...
前提条件gitをインストールする必要があるインストール手順1. リモートリポジトリからpyenvをク...
MySQL ページング クエリは通常、制限を通じて実装されます。 limit は 1 つまたは 2 ...
先ほど MySQL パスワードを設定したのに、外食したり荷物を受け取ったりするときにパスワードを忘れ...