文章目錄
- 對ES的一些疑問
- 問題1:ES相比mysql本身有哪些優勢?
- 問題2:哪些場景適合用ES而不是mysql?
- 問題3:mysql逐行掃描,根據過濾條件檢查記錄中對應字段是否滿足要求屬于正排索引,根據二叉樹索引檢索記錄的方式屬于正排索引還是倒排索引
- 問題4:對于簡單數字字段,為什么不像mysql一樣使用B+樹作為索引
- 一些概念
- 1、倒排索引
- 2、BKD樹
在模糊的影響中,ES查詢效率高,尤其是最近組內在推慢sql治理,看到有些單張表已經存在索引數量近10個,表中字段確實比較多,一種治理方式是寬表拆分多個表,降低每個表查詢的字段,每個表需要創建和維護索引數量也會降低。也在考慮是不是可以將數據同步到ES,部分查詢場景走ES,寬表拆分導致數據比較分散,更新和查詢起來更麻煩,使用ES數據完整性可以保證,相同數據使用不同的存儲介質進行存儲,更新和維護相比來說更簡單。這里不僅自問,增加mysql從庫從庫數量,降低查詢壓力不行嗎,同樣的數據同步到ES查詢,查詢效率就會顯著提升嗎?
對ES的一些疑問
問題1:ES相比mysql本身有哪些優勢?
1、ES會在所有字段上創建索引。
首先對于mysql中的數據同步到ES之后,會以JSON對象的形式進行存儲,mysql中一行記錄對應ES中一個文檔。索引字段都會被索引,對于文本和keyword字段會使用進行分詞、然后采用建立倒排索引,對于數值、日期等其它類型字段使用不同的數據結構和索引技術,例如對于數值和地理位置數據使用BKD樹。
2、水平擴展。
當數據量增加時,可以通過增加結點實現自動水平擴容,而mysql要實現水平擴容,往往需要手動操作,復雜度較大。
3、分布式檢索和并行處理。
ES天然將數據分片存儲,并行查詢時將每個分片上結果合并處理,mysql雖然也支持分庫分表,但分庫分表全部掃描效率相對較慢。
4、ES支持對文本進行全文檢索,比mysql的模糊查詢要快。
例如現在有一個用戶表,其中包含一個個人簡介profile字段,并且該表數據同步一份到了ES,二者要查詢喜歡唱歌的人,查詢方式分別如下,
對于Mysql,使用的是子字符串匹配算法:
SELECT * FROM users WHERE profile LIKE ‘%唱歌%’;
對于ES,使用倒排索引,顯而易見,效率更高:
GET /users/_search
{
“query”: {
“match”: {
“profile”: “唱歌”
}
}
}
問題2:哪些場景適合用ES而不是mysql?
場景 | mysql效率 | ES查詢效率 | 優先選擇 |
---|---|---|---|
簡單數字類型,數量不多 | 高,mysql使用起來更簡單,可視化效果更好 | 高,雖然也支持高效查詢,感覺不是很有必要,相比mysql更重 | mysql |
簡單數字類型,數量很多 | 通過建立索引和分庫分表依然可以勝任,但是維護和查詢復雜度會增高,水平分庫分表可以降低每個表的數據量,垂直分表可以減少單個表字段,提高單表查詢效率,跨表查詢將變得復雜,mysql寫入高,對于實時寫入場景要求高場景可以繼續使用mysql | 分布式擴展和并行查詢,大數量查詢效率高,并且天然支持水平擴展,寫入效率沒有mysql高,對于做聚合分析效率高,一般也會同步一份數據到ES,負責一些非實時的查詢 | mysql和ES同時使用 |
包含大文本 | 低,尤其模糊查詢 | 高,使用了倒排索引 | ES |
問題3:mysql逐行掃描,根據過濾條件檢查記錄中對應字段是否滿足要求屬于正排索引,根據二叉樹索引檢索記錄的方式屬于正排索引還是倒排索引
B+樹非葉子結點存儲記錄中某一列的值,葉子結點存儲記錄的id,倒排索引是根據某個詞查詢出所在的所有文檔列表,二者雖然都是從記錄中某個值查詢整個記錄的信息所在位置(唯一文檔標識或者記錄逐漸),但是二者一個是查詢出一條記錄,一個是查詢出這個單詞出現的所有文檔列表,差別還是很大的,一個用于大文本,一個用戶非大文本,專門解決的場景也不一樣。
問題4:對于簡單數字字段,為什么不像mysql一樣使用B+樹作為索引
首先從ES的定位來說,ES是為了提高多字段聯合查詢,雖然在多個字段上使用B+樹創建聯合索引,但是其實是將多個字段順序化,但其實在相近的數據,在空間上往往距離也很近,對于B+樹沒有保留數據的空間信息,查詢效率不是很高,而是使用使用了保留數據空間特征的BKD-Tree作為索引。
基于B+樹創建的聯合索引。
如下圖所示,創建和查詢都是優先表第一列,只有第一列相同才會比較第二列,這樣多維數據在邏輯上就變成了一維。
對于BKD樹,在創建索引,每層會依次按照k個緯度交替輪流進行劃分,這樣不用等第一維值全部檢索完才能利用后面緯度數據進行數據查找,如下圖依次是二維和三維BKD樹的的示意圖,對于二維BKD樹,奇數層次按照第一維度劃分,偶數層次按照第二維進行劃分,依次交替。
一些概念
1、倒排索引
倒排索引,也成為方向索引,是一種常用在文檔檢索系統中的索引方法,包含兩種形式,第一種,反向文檔索引一條記錄的水平反向索引,包含每個單詞所在文檔列表;第二種,完全反向索引一個單詞的水平反向索引,包含每個單詞在一個文檔中位置。三條記錄,舉例說明,:
T0=“what is banann”
T1= “it is what is it”
T2=“it is a banana”
反向文檔索引:
“a” : {2}
“banana”: {0,2}
“is” :{0,1,2}
“it”:{1,2}
“what”:{0,1}
完全反向索引:
“a” : {(2,2)}
“banana”: {(2,3)}
“is” :{(0,1),(1,1),(1,3),(2,1)}
“it”:{(1,0),(1,4),(2,0)}
“what”:{(0,0),()1,2}
比如查詢條件為“What”, “is”, “it”,計算每個關鍵詞出現的文檔取交集{0,1}∩{0,1,2}∩{1,2}={2},使用完全反向索引同理,只會對文檔位置取交集,例子三條記錄是正向索引,根據文檔id,檢索每個文檔包含的內容。
2、BKD樹
BKD樹全稱為Block-K-dimension Tree,是多維樹(K-dimension Tree,KD-Tree)的改良版本,改善了內存利用率和更好的查詢效率,多用于多維數據搜索。