MySQL-すべてのフィールドにインデックスを付けないのはなぜですか?


107

最近、インデックスの素晴らしさを学び、パフォーマンスが劇的に向上しました。しかし、私が学んだすべてのことを考えると、この質問に対する答えを見つけることができないようです。

インデックスは素晴らしいですが、なぜすべてのフィールドにインデックスを付けて、テーブルを信じられないほど高速にできないのでしょうか。これを行わないのには十分な理由があると思いますが、30フィールドテーブルの3つのフィールドはどうでしょうか。30フィールドで10?どこに線を引くべきか、そしてその理由は?


7
インデックスが付けられた1万を超えるエントリがあるテーブルに値を挿入してみてください。挿入/削除のためにすべてのエントリを更新する必要があります。これは、各値にインデックスがある場合、膨大な時間オーバーヘッドとメモリオーバーヘッドの一部になります
Jesus Ramos

5
スペースと書き込みのパフォーマンスの他に、もう1つの理由があります単一のテーブルアクセスに複数のインデックスを使用するのは非常に非効率的です。つまり、各列に1つのインデックスがある場合でも、WHERE句で複数の列にアクセスすると、選択のパフォーマンスはあまり良くありません。その場合、複数列のインデックスが最適です。
Markus Winand

1
30個のフィールドを持つテーブルがある場合は、テーブル構造を実際に確認する必要があります。非常に扱いにくいはずです。
ウェブ

回答:


122

インデックスはメモリ(RAM)の領域を占有します。インデックスが多すぎるか、または大きすぎるため、DBはそれらをディスクとの間で交換する必要があります。また、挿入時間と削除時間も増加します(各インデックスは、挿入/削除/更新されたすべてのデータについて更新する必要があります)。

あなたは無限の記憶を持っていません。すべてのインデックスがRAMに収まるようにする=良い。

あなたには無限の時間はありません。インデックスを作成する必要のある列のみにインデックスを作成すると、挿入、削除、更新のパフォーマンスへの影響が最小限に抑えられます。


11
一般的な理解を提供するためのさりげない答えですが、インデックスのどこに線を引くかを実際に決定するのにはあまり役立ちません。どうやって知ることができますか?それらを一般的なWHEREDフィールドに追加して、最高のものを望みますか?
Andrew

@アンドリュー一年半後、あなたの質問への答えを見つけましたか?
シンジャイ

1
@Sinjai一般的な場所にそれらを追加することは、おそらく経験則です。しかし、それ以外の場合は、インデックスの専門家になりたい場合は、多くの読書を行うことができます。例えば。stackoverflow.com/questions/3049283/...
アンドリュー・

ディスク容量を忘れないでください。
jpmc26

27

行が更新、挿入、または削除されるたびに、すべてのインデックスを更新する必要があることに注意してください。したがって、インデックスが多いほど、書き込み操作のパフォーマンスが低下します。

また、すべてのインデックスはさらにディスクスペースとメモリスペースを消費するため(呼び出された場合)、読み取り操作も遅くなる可能性があります(大きなテーブルの場合)。 これをチェック


6
リンクはMS SQL Server用です。この質問はMySQL
OMGポニー

5
@OMGリンクのほとんどのポイントは、すべての主要なRDBMSに適用されます
RichardTheKiwi '27年

5
@Richard aka cyberkiwi:インデックスはANSIの対象外です-これは各ベンダーが同様の用語を使用した奇跡です。しかしそれでも、SQL ServerとMySQLのみが「クラスター化」および「非クラスター化」インデックスという用語を使用しています。つまり、SQL Serverでは、MySQLよりも多くのことを意味しています。あるベンダーの推奨事項が別のベンダーに適用されることを保証するものは何もありません。
OMGポニー2011年

3
@omg最初の6ポイントはすべてのdbmsに適用されます。非/クラスター化されたものをスキップしてから、下にあるのは、一般的なインデックス作成に関するポイントです。あなたが指摘したい特定の事柄がある場合は、それらを呼び出します。それ以外の場合は、コメントから削除された回答を含むすべての回答を否定しているように見え、誰もあなたの評価に同意しません。
RichardTheKiwi 2011年

10

CRUDのニーズのバランスを取る必要があります。テーブルへの書き込みが遅くなります。どこに線を引くかについては、それはデータへのアクセス方法(ソートフィルタリングなど)によって異なります。


また、すべてのインデックスはいくつかのデータベース領域を使用します
Acanthus 2011年

@Acanthus:利用可能な最小のハードドライブはギガバイト単位で測定されます。
OMGポニー2011年

4
@OMGですが、Brianが指摘しているRAMではありません。必要以上に保存することは決して良い考えではありません。RAM内のデータ/インデックスキャッシング、バックアップメディア(テープごとに収まるバージョンなど)はすべて、無用なインデックスの影響を受けます
RichardTheKiwi

9
リソースの豊富さは、無駄や非効率の理由にはなりません。
スマンドリ

6
本当ですが、制約は10年以上前のものではありません。
OMGポニー2011年

2

インデックス作成は、ドライブとRAMの両方から割り当てられたスペースをより多く消費しますが、パフォーマンスも大幅に向上します。残念ながら、それがメモリ制限に達すると、システムはドライブスペースを解放し、パフォーマンスにリスクをもたらします。実際には、挿入や検索(WHERE句)のいずれでもない、あらゆる種類のデータトラバースアルゴリズムに関与しないと思われるフィールドのインデックスを作成しないでください。しかし、そうでなければあなたはすべきです。デフォルトでは、すべてのフィールドにインデックスを付ける必要があります。インデックスを解除することを検討する必要があるフィールドは、クエリがモデレーターのみによって使用される場合であり、速度も必要でない場合を除きます。


2

この答えは私の個人的な意見に基づいています

2番目の質問は、停止する境界線に関するものでした。最初に、いくつかの数学的な計算を行います。すべてのフィールドにインデックスを付けると、すべてのテーブルが並べ替えられるL個の新しいインデックステーブルを取得する場合、テーブルにL個のフィールドがあるN行があるとします。インデックスフィールドのデータの意味のある方法、一見すると、テーブルがWの重みである場合、100個の大きなテーブルがある場合、W * 2(1テラは2テラになります)になります(テーブル番号があったプロジェクトですでに作業していました)約1800テーブル)このスペースの100倍(100テラ)を無駄にします。これは賢明な方法とはかけ離れています。

すべてのテーブルにインデックスを適用する場合、インデックスの更新が1つの更新トリガーであり、すべてのインデックスが更新されると考える必要があります。

これから私はあなたがこのシナリオであなたが持っていると結論づけます。この時間を失うと、選択または更新でそれを失うことが望ましいです。なぜなら、インデックス付けされていないフィールドを選択すると、すべてのフィールドで別の選択がトリガーされないためです。インデックス付けされていません

何を索引付けするのですか?

foreign-keys:に基づく必要があります

主キー:誰かがこれを読んでこのケースで役立つかどうかはまだわかりません

他のフィールド:最初の自然な答えは残りのフィールドの半分です理由:インデックスを増やす必要がある場合、ベストインデックスからそれほど遠くない場合インデックスを少なくする必要がある場合も、インデックスがなく、すべてのインデックスが付いていることがわかっているため、それほど遠くないはずです。また悪いです。

この3つの点から、K個のキーで構成されるL個のフィールドがある場合、制限は((L-K)/2)+KL / 10程度の多少の差があると結論付けることができます

この答えは私の論理と個人の価格に基づいています


1

テーブルのすべての列にインデックスを付けることはお勧めできません。これにより、テーブルの読み取りが非常に高速になりますが、書き込みも非常に遅くなります。すべての列にインデックスが付けられているテーブルに書き込むには、そのテーブルに新しいレコードを配置してから、各列の情報を独自のインデックステーブルに配置します。


特に、データテーブルが100 MBのみで、index.tableが300 MB以上の場合、テーブルの読み取りが高速になるかどうかはわかりません。
David

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