7.1 指数の出現理由

それなしではデータベースは成り立たないもう 1 つの重要なものは、インデックスです。

userテーブルに 1,000 万人のユーザーがいて、90 を超えるレベルを持つ全員を表示したい状況を想像してください。このクエリは非常に簡単に作成できます。

SELECT * FROM user WHERE level > 90

見事、リクエストは 1 分以内に書き上げました。SQL サーバーからこのクエリを実行するにはどれくらい時間がかかりますか? このようなクエリを実行するには、1,000 万件のレコードを調べる必要があり、レコードが 1 つしかない場合でも、かなりの時間がかかります。

Java で同様のタスクを実行するにはどうすればよいでしょうか? まずユーザーのコレクションをレベルごとに並べ替え、次に二分検索を使用して必要なレコードをすばやく見つけることができました。それが何であるかを説明する必要はないと思いますか?

それはいいのですが、登録日が 2020 年より前のユーザーを選択する必要がある場合はどうすればよいでしょうか? 登録日順に再度並べ替えて二分検索を使用します。

そうですね、あるフィールドに対してフィルターを一度だけではなく頻繁に実行する場合、このフィールドで並べ替えられたデータを保存すると非常に便利です。

そして、異なるフィールドごとに同時に並べ替えられたデータを保存するにはどうすればよいでしょうか?

その答えは非常に簡単です。データそのものではなく、そのインデックスをグローバル テーブルに保存する必要があります。

ID: のユーザーが 10 人いるとします{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

そして、それらをレベルで並べ替えることにすると、その ID の配列は、たとえば次のようになります{9, 2, 3, 1, 5, 4, 8, 6, 7, 10}

そして、それらを日付で並べ替えると、たとえば次のようになります{10, 1, 8, 7, 2, 3, 5, 9, 6}

これらの ID の配列はインデックスと呼ばれます。要素自体は大きいので、触れません。Java では、オブジェクトには触れませんが、その参照を保存します。SQL では、実際の文字列には触れませんが、その数値を保存します。

これを Java コードで書き直してみましょう。

List<String> list = List.of("A", "C", "B", "Z", "Cc", "Bb", "Zz", "Y");  //this is a list of objects
List<String> alphabeticsList = new ArrayList(list);
Collections.sort(alphabeticsList); //collection sorted alphabetically

List<String> lengthList = new ArrayList(list);
Collections.sort(lengthList, lengthComparator); //collection sorted by string length

コレクションの並べ替えは、実際の要素を移動することを意味するものではありません。コレクションには実際のオブジェクトは保存されませんが、オブジェクトへのリンクが保存されます。SQL テーブルについても同様です。本当のセリフは自分自身に嘘をつき、嘘をつきます。

また、あるフィールドを頻繁に選択する必要がある場合は、別のインデックスをテーブルに追加し(Java の新しいコレクションに似ています)、テーブルの行を並べ替えて、その並べ替え順序を特別なインデックス ファイルに保存します。

Java の比較が少しでも役に立てば幸いです。少し練習すれば、インデックスの使用が最も明白な解決策になるでしょう。

7.2 テーブルへのインデックスの追加

インデックスはテーブルの作成中にすぐに指定することも、作成後に追加することもできます。ほとんどの場合、これは 2 番目のシナリオであり、テーブル サイズが大きくなり、データ サンプリングが遅くなるにつれてインデックスが追加されます。

テーブルにインデックスを追加するのは非常に簡単です。

ALTER TABLE table
    ADD INDEX index_name (column);

複数の列のレコードを同時に検索することが多い場合は、複合インデックスを指定できます。SQL は複数の列を使用してインデックスを構成します。

複合インデックスをテーブルに追加するのも非常に簡単です。

ALTER TABLE table
    ADD INDEX index_name (column 1, column 2, column 3, ...);

インデックスは多くのディスク領域を占有するため、インデックスが必要なくなった場合は、いつでも削除できます。

ALTER TABLE table
    DROP INDEX index_name;

インデックス自体は、データベースのかなり隠された部分です。これらは、クエリの作成形式にはまったく影響しません。ただ、それらの存在によりデータのサンプリングが高速化され、追加とバックアップが遅くなります。

しかし、今日の世界では速度がいかに重要であるか、そしてディスク容量がどれほど安いかを考えると、あらゆる場面で自由にインデックスを追加してください。管理人さん、ごめんなさい…