1

テーブル 't_table1' には 3 つのフィールドが含まれています。

`field1` tinyint(1) unsigned default NULL,
`field2` tinyint(1) unsigned default NULL,
`field3` tinyint(1) unsigned NOT NULL default ’0′,

およびインデックス:

KEY `t_table1_index1` (`field1`,`field2`,`field3`),

この SQL1 を実行すると:

EXPLAIN SELECT * FROM table1 AS c WHERE c.field1 = 1 AND c.field2 = 0 AND c.field3 = 0

次にショーです:

Select type: Simple
tyle: All
possible key: t_table1_index1
key: NULL
key_len: NULL
rows: 1042
extra: Using where

この場合、私のインデックスは役に立たないと言っていると思います。

しかし、この SQL2 を実行すると:

EXPLAIN SELECT * FROM table1 AS c WHERE c.field1 = 1 AND c.field2 = 1 AND c.field3 = 1

それが示している:

Select type: Simple
tyle: ref
possible key: t_table1_index1
key: t_table1_index1
key_len: 5
ref: const, const, const
rows: 1
extra: Using where

この場合、それは私のインデックスを使用しました。だから私のために説明してください:

  1. なぜSQL1はインデックスを使用できないのですか?

  2. SQL1 では、インデックスを編集したり、SQL を書き直してより迅速に実行するにはどうすればよいですか?

ありがとう !

4

1 に答える 1

0

クエリ オプティマイザーは、多くのデータ ポイントを使用して、クエリの実行方法を決定します。それらの 1 つは、インデックスの選択性です。インデックスを使用するには、エンジンがインデックスを読み取ってから実際の行をフェッチする必要があるため (インデックスだけでクエリ全体を満たすことができない場合)、テーブル スキャンよりも返される行ごとに多くのディスク アクセスが必要になる可能性があります。インデックスの選択性が低下する (基準に一致する行が増える) と、そのインデックスの使用効率が低下します。ある時点で、完全なテーブル スキャンを実行する方が安価になります。

2 番目の例では、オプティマイザーは、指定した値が 1 つの行のみをフェッチすることを確認できたので、インデックス ルックアップが正しいアプローチでした。

最初の例では、値はあまり選択的ではなく、1776 行のうち 1042 行が返されると見積もられていました。インデックスを使用すると、インデックスが検索され、選択された行参照のリストが作成され、各行がフェッチされます。非常に多くの行が選択されているため、インデックスを使用すると、テーブル全体を単純にスキャンして行をフィルタリングするよりも多くの作業が必要になります。

于 2013-01-23T20:33:18.157 に答える