7.1 指數出現的原因

沒有它就沒有數據庫的另一個重要的事情是索引。

想像這樣一種情況,用戶表中有 1000 萬用戶,你想顯示所有級別在 90 以上的用戶。這個查詢寫起來很簡單:

SELECT * FROM user WHERE level > 90

太好了,我們在不到一分鐘的時間內就寫好了請求。從 SQL 服務器執行此查詢需要多長時間?要執行這樣的查詢,他要翻一千萬條記錄,就算只有一條記錄,也需要很多時間。

我們如何在 Java 中完成類似的任務?我們首先將用戶集合按級別排序,然後我們可以使用二分查找非常快速地找到所需的記錄。我希望我不需要解釋它是什麼?

很好,但是如果我們現在需要選擇註冊日期在 2020 年之前的用戶怎麼辦?按註冊日期再次排序並使用二進制搜索。

是的,如果我們對某個字段執行過濾,而且不是一次,而是經常,那麼存儲按該字段排序的數據將非常有用。

以及如何存儲按不同字段同時排序的數據?

答案很簡單——你需要存儲的不是數據本身,而是它們在某個全局表中的索引。

假設有 10 個用戶的 id:{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 的數組稱為 indexes。元素本身很大,我們不碰它們。在 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 為表添加索引

索引可以在創建表時立即指定,也可以在創建之後添加。大多數情況下,它是第二種情況——隨著表大小的增長和數據採樣速度的減慢而添加索引。

為表添加索引非常簡單:

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;

索引本身是數據庫的一個相當隱藏的部分。它們不會以任何方式影響編寫查詢的格式。只是它們的存在加快了數據採樣的速度,減慢了它們的添加和備份速度。

但考慮到當今世界速度的重要性以及磁盤空間的廉價程度,請隨意為所有場合添加索引。管理員見諒...