EXPLAIN出力は、私のインデックスが使用されていないことを示唆しています


9

私はテーブルにdone_status(done_status = INT)のみのインデックスを設定しました:

ここに画像の説明を入力してください

私が使うとき:

EXPLAIN SELECT * FROM reminder  WHERE done_status=2

私はこれを取り戻します:

id select_typeテーブルタイプの可能性ありのキーキーのkey_len ref rows Extra
1簡単なリマインダーALL done_status NULL NULL NULL 5 whereの使用

しかし、このコマンドを発行すると:

EXPLAIN SELECT * FROM reminder  WHERE done_status=1

以下が返されます:

id select_typeテーブルタイプの可能性ありのキーキーのkey_len ref rows Extra
1 SIMPLE reminder ref done_status done_status 4 const 2   

EXPLAINそれは5行、二回目2行を使用していることを示してくれ。

インデックスが使用されているとは思いません。最初に正しく理解した場合は、3行になるはずです。何が悪いのでしょうか?

SHOW INDEX FROM reminder

テーブルNon_unique Key_name Seq_in_index Column_name Collat​​ion Cardinality Sub_part Packed Null Index_type Comment Index_comment
リマインダー1 done_status 1 done_status A 5 NULL NULL BTREE

拡張説明:

id select_typeテーブルタイプ
1 SIMPLE reminder ref done_status done_status 4 const 2 100.00

show warnings 何も興味を示さなかった。


インデックスが機能することを信じてください。しかし、スクリーンショットでは何も簡単に見ることができません。「yourtableからのインデックスの表示」を実行できますか

はい、私の質問を編集しました

スキーマには
glorify

興味がわからない場合は、「拡張された説明」と「警告を表示」で繰り返すことができます。これにより、mysqlが実際に選択したSQLが表示されます

@ajreal栄光とは何ですか?

回答:


4

「行」フィールドが何であるかを誤解している。これは、mysqlがクエリを満たすために読み取る必要があると推定する行数です。この値は非常に不正確になる可能性があります。これが結果の行数、またはmysqlによって読み取られた実際の行数であることを意味するものではありません


そう?どこでそうだと言ったの?オプティマイザが選択するのはそれ次第です。インデックスは引き続き機能します。

@ajrealただし、インデックスが壊れているわけではありません。オプティマイザがデータを照会するための最も効率的な方法を(念頭に置いて)選択するだけです。OPはEXPLAINの行列が正確であることを期待していると想定しました。インデックスが壊れているという意味ではありません-mysqlが(おそらく)使用しないことを選択しているだけです。

1
@ajreal:私はあなたの点で何かが欠けています。説明の行列は、インデックスとは関係ありませんか?Mysqlはインデックスを使用しないことを選択します(おそらくすべてのデータが単一のページにあります)。私はあなたのポイントを理解していますか?5行のテーブルに対するクエリの最適化では、最適化の方法はほとんど問題にならないため、「奇数」の結果が生成されます。


この場合、オプティマイザが選択するインデックスを気にするのは誰ですか?オプティマイザはインデックスを必要としないように感じたので、インデックス自体に問題はありません。何が問題なのでしょうか。

3

最初の実行プレーンはインデックスを確実に利用
していません。インデックスのinformation_schema.statisticsが書き込み操作の後にデータに追いつかないか、テーブルが長時間アクセスされていない可能性があります。

ここで説明するように: -MySQL Query Optimizerはどこからインデックス統計を読み取りますか?

2番目の実行プランでは、information_schema.statisticsがすでに追いついてNULLカーディナリティの問題を修正しているようです。

したがって、インデックスオプティマイザに従ってクエリを実行します。

行が小さいテーブルの場合は、それほど問題ではありません。
ただし、データは増加します。開発者は常にこれをチェック
し、インデックスでカーディナリティがnullの場合に必要な分析テーブルを実行する必要があります。


0

最初の実行プランはインデックスを使用していません。

MySQLリファレンスWebサイトから:

MySQLは、たとえ使用可能であっても、インデックスを使用しない場合があります。これが発生する状況の1つは、インデックスを使用するにはMySQLがテーブル内の行の非常に大きな割合にアクセスする必要があるとオプティマイザが推定する場合です。(この場合、必要なシークが少ないため、テーブルスキャンの方がはるかに高速です。)ただし、そのようなクエリがLIMITを使用して一部の行のみを取得する場合、MySQLはとにかくインデックスを使用します。結果で返す数行。

テーブルに5行しかなく、クエリが3行を選択する場合、MySQLオプティマイザーはテーブル全体をスキャンする方が効率的であると想定します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.