40

次のクエリでは

SELECT  col1,col2
FROM    table1
WHERE   col3='value1'
  AND   col4='value2'

col3に 1 つ、 col4にもう1 つの2 つの個別のインデックスがある場合、このクエリではどちらが使用されますか?

クエリ内の各テーブルに対して 1 つのインデックスのみが使用されていることをどこかで読みました。クエリが両方のインデックスを使用する方法がないということですか?

第 2 に、 col3col4の両方を一緒に使用して複合インデックスを作成し、WHERE句でcol3のみを使用すると、パフォーマンスが低下しますか? 例:

SELECT  col1,col2
FROM    table1
WHERE   col3='value1'

Lastly, Is it better to just use Covering indexes in all cases ? and does it differ between MYISAM and innodb storage engines ?

4

4 に答える 4

46

カバリング インデックスは複合インデックスと同じではありません。

col3 に 1 つ、col4 にもう 1 つの 2 つの個別のインデックスがある場合、このクエリではどちらが使用されますか?

カーディナリティが最も高いインデックス。
MySQL は、どのインデックスがどのプロパティを持つかに関する統計を保持します。
(MySQL の統計で明らかなように) 最も識別力のあるインデックスが使用されます。

クエリ内の各テーブルに対して 1 つのインデックスのみが使用されていることをどこかで読みました。それは、クエリが両方のインデックスを使用する方法がないということですか?

副選択を使用できます。
または、col3 と col4 の両方を含む複合インデックスを使用することをお勧めします。

第 2 に、col3 と col4 の両方を一緒に使用して複合インデックスを作成し、WHERE 句で col3 のみを使用すると、パフォーマンスが低下しますか? 例:

複合インデックス
正しい用語はcompoundインデックスであり、複合インデックスではありません。複合インデックスの一番左の部分
のみが使用されます。 したがって、インデックスが次のように定義されている場合

index myindex (col3, col4)  <<-- will work with your example.
index myindex (col4, col3)  <<-- will not work. 

参照: http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html

一番左のフィールドを選択すると、where 句でインデックスのその部分を使用しなくても済むことに注意してください。
複合インデックスがあると想像してください

Myindex(col1,col2)

SELECT col1 FROM table1 WHERE col2 = 200  <<-- will use index, but not efficiently
SELECT * FROM table1 where col2 = 200     <<-- will NOT use index.  

これが機能する理由は、最初のクエリがカバリング インデックスを使用し、それをスキャンするためです。
2 番目のクエリはテーブルにアクセスする必要があるため、インデックスをスキャンしても意味がありません。
これは InnoDB でのみ機能します。

カバリング
インデックスとは カバリング インデックスとは、クエリで選択されたすべてのフィールドがインデックスによる場合を指しますcovered。その場合、InnoDB (MyISAM ではない) はテーブルのデータを読み取ることはなく、インデックスのデータのみを使用します選択を高速化します。
InnoDB では、プライマリ キーはすべてのセカンダリ インデックスに含まれているため、ある意味ですべてのセカンダリ インデックスは複合インデックスであることに注意してください。
これは、InnoDB で次のクエリを実行すると、次のことを意味します。

SELECT indexed_field FROM table1 WHERE pk = something

MySQL は常にカバリング インデックスを使用し、実際のテーブルにはアクセスしません。 カバリング インデックスを使用することもできますがPRIMARY KEY、ヒットする必要があるのは 1 行のみであるため、 を優先します。

于 2011-11-21T14:28:46.057 に答える
5

完全を期すためにヨハンの答えに賛成しましたが、セカンダリインデックスに関する彼の次の発言は間違っているか、混乱していると思います。

Note that in InnoDB the primary key is included in all secondary indexes, 
so in a way all secondary indexes are compound indexes.

This means that if you run the following query on InnoDB:

SELECT indexed_field FROM table1 WHERE pk = something

MySQL will always use a covering index and will not access the actual table.

主キーがセカンダリ インデックスに含まれていることに同意しますが、ここで指定された SELECT クエリでMySQL が「常にカバリング インデックスを使用する」ことに同意しません。

理由を確認するには、この場合は常に完全なインデックス「スキャン」が必要であることに注意してください。これは「シーク」操作と同じではなく、セカンダリ インデックスの内容を 100% スキャンします。これは、副次索引が主キーによって順序付けられていないためです。それは "indexed_field" によって順序付けられます (そうでなければ、インデックスとしてはあまり役に立ちません! )。

この後者の事実に照らして、主キーを「シーク」してから、セカンダリ インデックスからではなく「実際のテーブルから」indexed_field を抽出する方が効率的な場合があります。

于 2013-11-21T19:46:04.020 に答える
1

これは私がよく耳にする質問であり、次の理由により、この問題に関して多くの混乱が生じています。

  • 何年にもわたる mySQL の違い。インデックスと複数インデックスのサポートは長年にわたって変更されました (サポートされる方向へ)

  • InnoDB / myISAM の違いいくつかの重要な違いがあります (以下) が、複数のインデックスがその 1 つだとは思いません

MyISAM は古いですが、実績があります。MyISAM テーブルのデータは、テーブル形式、データ、およびインデックスの 3 つの異なるファイルに分割されます。
InnoDB は MyISAM よりも比較的新しく、トランザクションセーフです。InnoDB は、マルチユーザーの同時実行性とパフォーマンスを向上させるテーブル ロックとは対照的に、行ロックも提供します。InnoDB には外部キー制約もあります。
その行ロック機能により、InnoDB は高負荷環境に適しています。

物事を確認するには、必ず Explain_plan を使用してクエリの実行を分析してください。

于 2011-11-21T14:36:13.460 に答える
-1

複合インデックスは、複合インデックスと同じではありません。

  • 複合インデックスは、フィルター、結合、および選択基準のすべての列をカバーします。これらの列はすべて、インデックス B ツリー全体に応じて、すべてのインデックス ページに格納されます。
  • 複合インデックスは、B ツリーのすべてのフィルターおよび結合キー列をカバーしますが、抽出されるだけではなく、検索されないため、選択列はリーフ ページにのみ保持されます。これによりスペースが節約されるため、作成されるインデックス ページが少なくなるため、I/O が高速になります。
于 2013-06-03T12:34:15.903 に答える