あなたは間違いなくインデックス作成にある程度の時間を費やす必要があり、それについて多くのことが書かれており、何が起こっているのかを理解することが重要です。
大まかに言えば、インデックスはテーブルの行に順序付けを課します。
簡単にするために、テーブルが単なる大きなCSVファイルであると想像してください。行が挿入されるたびに、行の最後に挿入されます。したがって、テーブルの「自然な」順序は、行が挿入された順序にすぎません。
そのCSVファイルが非常に初歩的なスプレッドシートアプリケーションに読み込まれたとしましょう。このスプレッドシートでは、データを表示し、行に順番に番号を付けます。
ここで、3番目の列に値「M」を持つすべての行を見つける必要があると想像してください。利用可能なものを考えると、1つのオプションしかありません。各行の3番目の列の値をチェックしてテーブルをスキャンします。行が多い場合、この方法(「テーブルスキャン」)には時間がかかることがあります。
このテーブルに加えて、インデックスがあると想像してください。この特定のインデックスは、3番目の列の値のインデックスです。インデックスは、3番目の列のすべての値を意味のある順序(たとえば、アルファベット順)で一覧表示し、それぞれについて、その値が表示される行番号のリストを提供します。
これで、3番目の列の値が「M」であるすべての行を見つけるための優れた戦略ができました。たとえば、バイナリ検索を実行できます。テーブルスキャンではN行(Nは行数)を検索する必要がありますが、バイナリ検索では、最悪の場合、log-nインデックスエントリを確認するだけで済みます。うわー、それは確かにはるかに簡単です!
もちろん、このインデックスがあり、テーブルに行を追加している場合(最後に、概念的なテーブルが機能しているため)、毎回インデックスを更新する必要があります。したがって、新しい行を書き込んでいる間はもう少し作業が必要ですが、何かを検索しているときは時間を大幅に節約できます。
したがって、一般に、インデックス付けは読み取り効率と書き込み効率のトレードオフを作成します。インデックスがない場合、挿入は非常に高速になります。データベースエンジンはテーブルに行を追加するだけです。インデックスを追加すると、エンジンは挿入の実行中に各インデックスを更新する必要があります。
一方、読み取りははるかに速くなります。
うまくいけば、最初の2つの質問がカバーされます(他の人が答えたように、適切なバランスを見つける必要があります)。
3番目のシナリオはもう少し複雑です。LIKEを使用している場合、インデックスエンジンは通常、最初の「%」までの読み取り速度に役立ちます。つまり、WHERE列LIKE 'foo%bar%'をSELECTしている場合、データベースは、インデックスを使用して、列が「foo」で始まるすべての行を見つけ、その中間行セットをスキャンしてサブセットを見つける必要があります。 「バー」が含まれています。SELECT ... WHERE列LIKE '%bar%'はインデックスを使用できません。その理由をご理解いただければ幸いです。
最後に、複数の列のインデックスについて考える必要があります。概念は同じで、LIKEのものと同様に動作します。基本的に、(a、b、c)にインデックスがある場合、エンジンは可能な限り左から右にインデックスを使用し続けます。したがって、列aの検索では、(a、b)の場合と同様に、(a、b、c)インデックスを使用できます。ただし、WHERE b = 5 AND c = 1)を検索する場合、エンジンは全表スキャンを実行する必要があります。
うまくいけば、これは少し光を当てるのに役立ちますが、これらのことを詳細に説明する良い記事を探すために数時間かけて過ごすことをお勧めします。特定のデータベースサーバーのドキュメントを読むこともお勧めします。クエリプランナーがインデックスを実装して使用する方法は、かなり大きく異なります。