想要搞清這個問題要從mysql和ES的索引數據結構下手,咱們先了解一下mysql的索引結構,然后再了解一下ES的索引結構,然后再進行對比這個問題就會很清楚了。
mysql關系型數據庫索引原理:
數據庫的索引是B+tree結構
主鍵索引是聚合索引,其他索引是非聚合索引
聚合索引:
可以通過主鍵直接找到數據。
非聚合索引:
如果mysql根據非聚合索引去查詢數據,首先要通過非聚合索引找到對應的主鍵id,再去根據主鍵id走聚合索引找到數據
Elasticsearch倒排索引原理:
在講倒排索引之前咱們先說一下正向索引
正向索引的結構就是每個文檔和關鍵字做關聯,每個文檔都有與之對應的關鍵字,記錄關鍵字在文檔中出現的位置和次數。但是用戶查詢的時候是根據關鍵字去查詢的。當用戶想要查詢“iPhone”,這時候會掃描所有文檔找出包含iPhone的文檔,可想而知當線上數據量非常龐大的情況下,這樣的索引結構根本無法滿足實時返回排名結果的要求。
倒排索引
倒排索引是根據關鍵詞去查找文檔的id,每個關鍵詞都會有與之對應的文檔id。倒排索引是實現“單詞-文檔矩陣”的一種具體存儲形式,通過倒排索引,可以根據單詞快速獲取包含這個單詞的文檔列表。倒排索引主要由三個部分組成:“單詞詞典”、“排序列表”和”“倒排文件”。
單詞詞典(Lexicon):搜索引擎的通常索引單位是單詞,單詞詞典是由文檔集合中出現過的所有單詞構成的字符串集合,單詞詞典內每條索引項記載單詞本身的一些信息以及指向“倒排列表”的指針。
倒排列表(PostingList):倒排列表記載了出現過某個單詞的所有文檔的文檔列表及單詞在該文檔中出現的位置信息,每條記錄稱為一個倒排項(Posting)。根據倒排列表,即可獲知哪些文檔包含某個單詞。
倒排文件(Inverted File):所有單詞的倒排列表往往順序地存儲在磁盤的某個文件里,這個文件即被稱之為倒排文件,倒排文件是存儲倒排索引的物理文件。
兩者對比:
第一種情況:
基於分詞后的全文檢索:例如select * from test where name like '%張三%',對於關系型數據庫mysql來說簡直是一種災難,因為會進行全表檢索,但是對es而言分詞后,每個字都可以利用FST高速找到倒排索引的位置,並迅速獲取文檔id列表,大大的提升了性能減少了磁盤IO。
第二種情況:
精確檢索:進行精確檢索,有些時候可能mysql要快一些,當mysql的非聚合索引引用上了覆蓋索引,無需回表,則速度上可能更快,但是es還是通過FST找到倒排索引的位置比獲取文檔id列表,再根據文檔id獲取文檔並根據相關度進行排序。但是es還有個優勢,就是es即天然的分布式使得在大量數據搜索時可以通過分片降低檢索規模,並且可以通過並行檢索提升效率,用filter時更是可以直接跳過檢索直接走緩存