4

countriesiso2列にインデックスを付けて、次のように構造化されたテーブルがあります。


ここに画像の説明を入力


通常の選択クエリを実行すると、iso2 インデックスは正常に機能します。


ここに画像の説明を入力


しかし、iso2 で別のテーブルと結合すると、非常に奇妙な動作をします。


ここに画像の説明を入力


まず、NULLpossible_keys と表示されていますが、それでも使用していますか? 次に、テーブル全体である 256 行とも表示されます。大きな更新では実行が非常に遅いため、インデックスを使用していないことがわかります。ここで何が問題なのですか?

編集: また、idiso2 インデックスから列を取り出すと (最初の図を参照)、結合で使用されているインデックスはないと表示されます。


詳細情報: データを正規化し、 のcountry_id代わりに を使用しようとしていcountryます。でテーブルを更新していたcountry_idときに、非常に遅くなっていることに気付きました。いくつかの EXPLAIN によって、インデックスが使用されていないことがわかりました。多分それは iso2 が char(2) であることと関係がありますか?

私は次のようにcountry_idを入力していました:

UPDATE leads
LEFT JOIN countries on leads.country=countries.iso2
SET leads.country_id=countries.id

leadsこのクエリは、テーブルの約 10 万行に対して約 40 秒かかりました。

4

1 に答える 1

0

これEXPLAINは完全なインデックス スキャンを実行していることを意味します。これは理想的ではありませんが、必ずしも悪いわけではありません。この場合は問題ありません。iso2インデックスは です。covering indexこれは、このクエリでそのテーブルから必要なすべての列が含まれていることを意味します。基本的に、クエリ オプティマイザーは、インデックスから必要な行を見つけて、テーブルからその行を読み取って を取得する代わりに、インデックスidの次の部分に移動することを決定しました。

オプティマイザーがインデックスで参照を使用することを期待していましたが、どうやらそれは有益ではないと判断したようです。インデックスは小さいので、インデックスの参照を使用しなくても心配ありません。

その他のいくつかのポイント:

  • 「大きなアップデートで非常に遅くなる」について詳しく教えてください。
  • テーブルは MyISAM または InnoDB を使用していますか?
  • countries.idSMALLINT UNSIGNEDおそらく;に変更できます。これは とほぼ同じINT(5)ですが、4 ではなく 2 バイトを使用します。
  • CHAR(2)に最適なデータ型ですiso2
于 2013-03-13T14:03:29.177 に答える