ElasticSearch還能效能調優,漲見識、漲見識了!!!

語言: CN / TW / HK

ElasticSearch 效能調優

img

  • 作者: 博學谷狂野架構師

  • GitHub地址:GitHub地址 (有我們精心準備的130本電子書PDF)

概述

效能優化是個涉及面非常廣的問題,不同的環境,不同的業務場景可能會存在不同的優化方案,本文只對一些相關的知識點做簡單的總結,具體方案可以根據場景自行嘗試。

配置檔案調優

通過elasticsearch.yml配置檔案調優

記憶體鎖定

允許 JVM 鎖住記憶體,禁止作業系統交換出去

由於JVM發生swap交換會導致極大降低ES的效能,為了防止ES發生記憶體交換,我們可以通過鎖定記憶體來實現,這將極大提高查詢效能,但同時可能造成OOM,需要對應做好資源監控,必要的時候進行干預。

修改ES配置

修改ES的配置檔案elasticsearch.yml,設定bootstrap.memory_lock為true

COPY#叢集名稱
cluster.name: elastic
#當前該節點的名稱
node.name: node-3
#是不是有資格競選主節點
node.master: true
#是否儲存資料
node.data: true
#最大叢集節點數
node.max_local_storage_nodes: 3
#給當前節點自定義屬性(可以省略)
#node.attr.rack: r1
#資料存檔位置
path.data: /usr/share/elasticsearch/data
#日誌存放位置
path.logs: /usr/share/elasticsearch/log
#是否開啟時鎖定記憶體(預設為是)
#bootstrap.memory_lock: true
#設定閘道器地址,我是被這個坑死了,這個地址我原先填寫了自己的實際物理IP地址,
#然後啟動一直報無效的IP地址,無法注入9300埠,這裡只需要填寫0.0.0.0
network.host: 0.0.0.0
#設定對映埠
http.port: 9200
#內部節點之間溝通埠
transport.tcp.port: 9300
#叢集發現預設值為127.0.0.1:9300,如果要在其他主機上形成包含節點的群集,如果搭建叢集則需要填寫
#es7.x 之後新增的配置,寫入候選主節點的裝置地址,在開啟服務後可以被選為主節點,也就是說把所有的節點都寫上
discovery.seed_hosts: ["node-1","node-2","node-3"]
#當你在搭建叢集的時候,選出合格的節點叢集,有些人說的太官方了,
#其實就是,讓你選擇比較好的幾個節點,在你節點啟動時,在這些節點中選一個做領導者,
#如果你不設定呢,elasticsearch就會自己選舉,這裡我們把三個節點都寫上
cluster.initial_master_nodes: ["node-1","node-2","node-3"]
#在群集完全重新啟動後阻止初始恢復,直到啟動N個節點
#簡單點說在叢集啟動後,至少復活多少個節點以上,那麼這個服務才可以被使用,否則不可以被使用,
gateway.recover_after_nodes: 2
#刪除索引是是否需要顯示其名稱,預設為顯示
#action.destructive_requires_name: true
# 允許記憶體鎖定,提高ES效能
bootstrap.memory_lock: true
修改JVM配置

修改jvm.options,通常設定-Xms和-Xmx的的值為“實體記憶體大小的一半和32G的較小值”

這是因為,es核心使用lucene,lucene本身是單獨佔用記憶體的,並且佔用的還不少,官方建議設定es記憶體,大小為實體記憶體的一半,剩下的一半留給lucene

COPY-Xms2g
-Xmx2g
關閉作業系統的swap
臨時關閉
COPYsudo swapoff -a 
永久關閉

註釋掉或刪除所有swap相關的內容

COPYvi /etc/fstab

image-20220818104148323

修改檔案描述符

修改/etc/security/limits.conf,設定memlock為unlimited

COPYelk hard memlock unlimited
elk soft memlock unlimited
修改系統配置
設定虛擬記憶體

修改/etc/systemd/system.conf,設定vm.max_map_count為一個較大的值

COPYvm.max_map_count=10240000
修改檔案上限

修改/etc/systemd/system.conf,設定DefaultLimitNOFILE,DefaultLimitNPROC,DefaultLimitMEMLOCK為一個較大值,或者不限定

COPYDefaultLimitNOFILE=100000
DefaultLimitNPROC=100000
DefaultLimitMEMLOCK=infinity
重啟ES

服務發現優化

Elasticsearch 預設被配置為使用單播發現,以防止節點無意中加入叢集

組播發現應該永遠不被使用在生產環境了,否則你得到的結果就是一個節點意外的加入到了你的生產環境,僅僅是因為他們收到了一個錯誤的組播訊號,ES是一個P2P型別的分散式系統,使用gossip協議,叢集的任意請求都可以傳送到叢集的任一節點,然後es內部會找到需要轉發的節點,並且與之進行通訊,在es1.x的版本,es預設是開啟組播,啟動es之後,可以快速將區域網內叢集名稱,預設埠的相同例項加入到一個大的叢集,後續再es2.x之後,都調整成了單播,避免安全問題和網路風暴;

單播discovery.zen.ping.unicast.hosts,建議寫入叢集內所有的節點及埠,如果新例項加入叢集,新例項只需要寫入當前叢集的例項,即可自動加入到當前叢集,之後再處理原例項的配置即可,新例項加入叢集,不需要重啟原有例項;

節點zen相關配置:discovery.zen.ping_timeout:判斷master選舉過程中,發現其他node存活的超時設定,主要影響選舉的耗時,引數僅在加入或者選舉 master 主節點的時候才起作用discovery.zen.join_timeout:節點確定加入到叢集中,向主節點發送加入請求的超時時間,預設為3sdiscovery.zen.minimum_master_nodes:參與master選舉的最小節點數,當叢集能夠被選為master的節點數量小於最小數量時,叢集將無法正常選舉。

故障檢測( fault detection )

故障檢測情況

以下兩種情況下回進行故障檢測

COPY* 第一種是由master向叢集的所有其他節點發起ping,驗證節點是否處於活動狀態
* 第二種是:叢集每個節點向master發起ping,判斷master是否存活,是否需要發起選舉
配置方式

故障檢測需要配置以下設定使用

  • discovery.zen.fd.ping_interval :節點被ping的頻率,預設為1s。
  • discovery.zen.fd.ping_timeout 等待ping響應的時間,預設為 30s,執行的叢集中,master 檢測所有節點,以及節點檢測 master 是否正常。
  • discovery.zen.fd.ping_retries ping失敗/超時多少導致節點被視為失敗,預設為3。

佇列數量優化

不建議盲目加大es的佇列數量,要根據實際情況來進行調整

如果是偶發的因為資料突增,導致佇列阻塞,加大佇列size可以使用記憶體來快取資料,如果是持續性的資料阻塞在佇列,加大佇列size除了加大記憶體佔用,並不能有效提高資料寫入速率,反而可能加大es宕機時候,在記憶體中可能丟失的上資料量。

檢視執行緒池情況

通過以下可以檢視執行緒池的情況,哪些情況下,加大佇列size呢?

COPYGET /_cat/thread_pool

image-20220818111407007

觀察api中返回的queue和rejected,如果確實存在佇列拒絕或者是持續的queue,可以酌情調整佇列size。

記憶體使用

配置熔斷限額

設定indices的記憶體熔斷相關引數,根據實際情況進行調整,防止寫入或查詢壓力過高導致OOM

  • indices.breaker.total.limit: 50%,叢集級別的斷路器,預設為jvm堆的70%
  • indices.breaker.request.limit: 10%,單個request的斷路器限制,預設為jvm堆的60%
  • indices.breaker.fielddata.limit: 10%,fielddata breaker限制,預設為jvm堆的60%。
配置快取

根據實際情況調整查詢佔用cache,避免查詢cache佔用過多的jvm記憶體,引數為靜態的,需要在每個資料節點配置

  • indices.queries.cache.size: 5%,控制過濾器快取的記憶體大小,預設為10%,接受百分比值,5%或者精確值,例如512mb。

建立分片優化

如果叢集規模較大,可以阻止新建shard時掃描叢集內全部shard的元資料,提升shard分配速度

  • cluster.routing.allocation.disk.include_relocations: false,預設為true

系統層面調優

jdk版本

選用當前版本ES推薦使用的ES,或者使用ES自帶的JDK

jdk記憶體配置

首先,-Xms和-Xmx設定為相同的值,避免在執行過程中再進行記憶體分配,同時,如果系統記憶體小於64G,建議設定略小於機器記憶體的一半,剩餘留給系統使用,同時,jvm heap建議不要超過32G(不同jdk版本具體的值會略有不同),否則jvm會因為記憶體指標壓縮導致記憶體浪費

關閉交換分割槽

關閉交換分割槽,防止記憶體發生交換導致效能下降(部分情況下,寧死勿慢) swapoff -a

檔案控制代碼

Lucene 使用了 大量的 檔案,同時,Elasticsearch 在節點和 HTTP 客戶端之間進行通訊也使用了大量的套接字,所有這一切都需要足夠的檔案描述符,預設情況下,linux預設執行單個程序開啟1024個檔案控制代碼,這顯然是不夠的,故需要加大檔案控制代碼數 ulimit -n 65536

mmap

Elasticsearch 對各種檔案混合使用了 NioFs( 注:非阻塞檔案系統)和 MMapFs ( 注:記憶體對映檔案系統)。

請確保你配置的最大對映數量,以便有足夠的虛擬記憶體可用於 mmapped 檔案。這可以暫時設定:sysctl -w vm.max_map_count=262144 或者你可以在 /etc/sysctl.conf 通過修改 vm.max_map_count 永久設定它。

磁碟

如果你正在使用 SSDs,確保你的系統 I/O 排程程式是配置正確的

當你向硬碟寫資料,I/O 排程程式決定何時把資料實際傳送到硬碟,大多數預設linux 發行版下的排程程式都叫做 cfq(完全公平佇列),但它是為旋轉介質優化的:機械硬碟的固有特性意味著它寫入資料到基於物理佈局的硬碟會更高效。

這對 SSD 來說是低效的,儘管這裡沒有涉及到機械硬碟,但是,deadline 或者 noop 應該被使用,deadline 排程程式基於寫入等待時間進行優化, noop 只是一個簡單的 FIFO 佇列。

COPYecho noop > /sys/block/sd/queue/scheduler

磁碟掛載

COPYmount -o noatime,data=writeback,barrier=0,nobh /dev/sd* /esdata*

其中,noatime,禁止記錄訪問時間戳;data=writeback,不記錄journal;barrier=0,因為關閉了journal,所以同步關閉barrier;nobh,關閉buffer_head,防止核心影響資料IO

磁碟其他注意事項

使用 RAID 0,條帶化 RAID 會提高磁碟I/O,代價顯然就是當一塊硬碟故障時整個就故障了,不要使用映象或者奇偶校驗 RAID 因為副本已經提供了這個功能。

另外,使用多塊硬碟,並允許 Elasticsearch 通過多個 path.data 目錄配置把資料條帶化分配到它們上面,不要使用遠端掛載的儲存,比如 NFS 或者 SMB/CIFS。這個引入的延遲對效能來說完全是背道而馳的。

使用方式調優

當elasticsearch本身的配置沒有明顯的問題之後,發現es使用還是非常慢,這個時候,就需要我們去定位es本身的問題了,首先祭出定位問題的第一個命令:

Index(寫)調優

副本數置0

如果是叢集首次灌入資料,可以將副本數設定為0,寫入完畢再調整回去,這樣副本分片只需要拷貝,節省了索引過程

COPYPUT /my_temp_index/_settings
{
"number_of_replicas": 0
}
自動生成doc ID

通過Elasticsearch寫入流程可以看出,如果寫入doc時如果外部指定了id,則Elasticsearch會先嚐試讀取原來doc的版本號,以判斷是否需要更新,這會涉及一次讀取磁碟的操作,通過自動生成doc ID可以避免這個環節

合理設定mappings

將不需要建立索引的欄位index屬性設定為not_analyzed或no。

  • 對欄位不分詞,或者不索引,可以減少很多運算操作,降低CPU佔用,尤其是binary型別,預設情況下佔用CPU非常高,而這種型別進行分詞通常沒有什麼意義。
  • 減少欄位內容長度,如果原始資料的大段內容無須全部建立 索引,則可以儘量減少不必要的內容。
  • 使用不同的分析器(analyzer),不同的分析器在索引過程中 運算複雜度也有較大的差異。
調整_source欄位
_source` 欄位用於儲存 doc 原始資料,對於部分不需要儲存的欄位,可以通過 includes excludes過濾,或者將`_source`禁用,一般用於索引和資料分離,這樣可以降低 I/O 的壓力,不過實際場景中大多不會禁用`_source
對analyzed的欄位禁用norms

Norms用於在搜尋時計算doc的評分,如果不需要評分,則可以將其禁用

COPYtitle": {
"type": "string",
"norms": {
"enabled": false
}
調整索引的重新整理間隔

該引數預設是1s,強制ES每秒建立一個新segment,從而保證新寫入的資料近實時的可見、可被搜尋到,比如該引數被調整為30s,降低了重新整理的次數,把重新整理操作消耗的系統資源釋放出來給index操作使用

COPYPUT /my_index/_settings
{
 "index" : {
      "refresh_interval": "30s"
    }
}

這種方案以犧牲可見性的方式,提高了index操作的效能。

批處理

批處理把多個index操作請求合併到一個batch中去處理,和mysql的jdbc的bacth有類似之處

在這裡插入圖片描述

比如每批1000個documents是一個性能比較好的size,每批中多少document條數合適,受很多因素影響而不同,如單個document的大小等,ES官網建議通過在單個node、單個shard做效能基準測試來確定這個引數的最優值

Document的路由處理

當對一批中的documents進行index操作時,該批index操作所需的執行緒的個數由要寫入的目的shard的個數決定

在這裡插入圖片描述

有2批documents寫入ES, 每批都需要寫入4個shard,所以總共需要8個執行緒,如果能減少shard的個數,那麼耗費的執行緒個數也會減少,例如下圖,兩批中每批的shard個數都只有2個,總共執行緒消耗個數4個,減少一半。

預設的routing就是id,也可以在傳送請求的時候,手動指定一個routing value,比如說put/index/doc/id?routing=user_id

在這裡插入圖片描述

值得注意的是執行緒數雖然降低了,但是單批的處理耗時可能增加了。和提高重新整理間隔方法類似,這有可能會延長資料不見的時間

Search(讀)調優

在儲存的Document條數超過10億條後,我們如何進行搜尋調優

資料分組

很多人拿ES用來儲存日誌,日誌的索引管理方式一般基於日期的,基於天、周、月、年建索引,如下圖,基於天建索引

在這裡插入圖片描述

當搜尋單天的資料,只需要查詢一個索引的shards就可以,當需要查詢多天的資料時,需要查詢多個索引的shards,這種方案其實和資料庫的分表、分庫、分割槽查詢方案相比,思路類似,小資料範圍查詢而不是大海撈針。

開始的方案是建一個index,當資料量增大的時候,就擴容增加index的shard的個數,當shards增大時,要搜尋的shards個數也隨之顯著上升,基於資料分組的思路,可以基於client進行資料分組,每一個client只需依賴自己的index的資料shards進行搜尋,而不是所有的資料shards,大大提高了搜尋的效能,如下圖:

在這裡插入圖片描述

使用Filter替代Query

在搜尋時候使用Query,需要為Document的相關度打分,使用Filter,沒有打分環節處理,做的事情更少,而且filter理論上更快一些。

如果搜尋不需要打分,可以直接使用filter查詢,如果部分搜尋需要打分,建議使用’bool’查詢,這種方式可以把打分的查詢和不打分的查詢組合在一起使用,如

COPYGET /_search
{
"query": {
"bool": {
"must": {
"term": {
"user": "kimchy"
}
},
"filter": {
"term": {
"tag": "tech"
}
}
}
}
}
ID欄位定義為keyword

一般情況,如果ID欄位不會被用作Range 型別搜尋欄位,都可以定義成keyword型別,這是因為keyword會被優化,以便進行terms查詢,Integers等數字類的mapping型別,會被優化來進行range型別搜尋,將integers改成keyword型別之後,搜尋效能大約能提升30%

hot_threads

可以使用以下命令,抓取30s區間內的節點上佔用資源的熱執行緒,並通過排查佔用資源最多的TOP執行緒來判斷對應的資源消耗是否正常

COPYGET /_nodes/hot_threads&interval=30s

一般情況下,bulk,search類的執行緒佔用資源都可能是業務造成的,但是如果是merge執行緒佔用了大量的資源,就應該考慮是不是建立index或者刷磁碟間隔太小,批量寫入size太小造成的。

image-20220818113055536

pending_tasks

有一些任務只能由主節點去處理,比如建立一個新的索引或者在叢集中移動分片,由於一個叢集中只能有一個主節點,所以只有這一master節點可以處理叢集級別的元資料變動

在99.9999%的時間裡,這不會有什麼問題,元資料變動的佇列基本上保持為零,在一些罕見的叢集裡,元資料變動的次數比主節點能處理的還快,這會導致等待中的操作會累積成佇列,這個時候可以通過pending_tasks api分析當前什麼操作阻塞了es的佇列,比如,叢集異常時,會有大量的shard在recovery,如果叢集在大量建立新欄位,會出現大量的put_mappings的操作,所以正常情況下,需要禁用動態mapping。

COPYGET /_cluster/pending_tasks

image-20220818113227223

欄位儲存

當前es主要有doc_values,fielddata,storefield三種類型,大部分情況下,並不需要三種類型都儲存,可根據實際場景進行調整:

當前用得最多的就是doc_values,列儲存,對於不需要進行分詞的欄位,都可以開啟doc_values來進行儲存(且只保留keyword欄位),節約記憶體,當然,開啟doc_values會對查詢效能有一定的影響,但是,這個效能損耗是比較小的,而且是值得的;

fielddata構建和管理 100% 在記憶體中,常駐於 JVM 記憶體堆,所以可用於快速查詢,但是這也意味著它本質上是不可擴充套件的,有很多邊緣情況下要提防,如果對於欄位沒有分析需求,可以關閉fielddata;

storefield主要用於_source欄位,預設情況下,資料在寫入es的時候,es會將doc資料儲存為_source欄位,查詢時可以通過_source欄位快速獲取doc的原始結構,如果沒有update,reindex等需求,可以將_source欄位disable;

_all,ES在6.x以前的版本,預設將寫入的欄位拼接成一個大的字串,並對該欄位進行分詞,用於支援整個doc的全文檢索,在知道doc欄位名稱的情況下,建議關閉掉該欄位,節約儲存空間,也避免不帶欄位key的全文檢索;

norms:搜尋時進行評分,日誌場景一般不需要評分,建議關閉;

事務日誌

Elasticsearch 2.0之後為了保證不丟資料,每次 index、bulk、delete、update 完成的時候,一定會觸發同步重新整理 translog 到磁碟上,才給請求返回 200 OK

非同步重新整理

採用非同步重新整理,這個改變在提高資料安全性的同時當然也降低了一點效能,如果你不在意這點可能性,還是希望效能優先,可以在 index template 裡設定如下引數

COPY{
    "index.translog.durability": "async"
}
其他引數
index.translog.sync_interval

對於一些大容量的偶爾丟失幾秒資料問題也並不嚴重的叢集,使用非同步的 fsync 還是比較有益的,比如,寫入的資料被快取到記憶體中,再每5秒執行一次 fsync ,預設為5s,小於的值100ms是不允許的。

index.translog.flush_threshold_size

translog儲存尚未安全儲存在Lucene中的所有操作,雖然這些操作可用於讀取,但如果要關閉並且必須恢復,則需要重新編制索引,此設定控制這些操作的最大總大小,以防止恢復時間過長,達到設定的最大size後,將發生重新整理,生成新的Lucene提交點,預設為512mb。

refresh_interval

執行重新整理操作的頻率,這會使索引的最近更改對搜尋可見,預設為1s,可以設定-1為禁用重新整理,對於寫入速率要求較高的場景,可以適當的加大對應的時長,減小磁碟io和segment的生成;

禁止動態mapping

動態mapping的缺點
  1. 造成叢集元資料一直變更,導致 不穩定;
  2. 可能造成資料型別與實際型別不一致;
  3. 對於一些異常欄位或者是掃描類的欄位,也會頻繁的修改mapping,導致業務不可控。
對映配置

動態mapping配置的可選值及含義如下

  • true:支援動態擴充套件,新增資料有新的欄位屬性時,自動新增對於的mapping,資料寫入成功
  • false:不支援動態擴充套件,新增資料有新的欄位屬性時,直接忽略,資料寫入成功
  • strict:不支援動態擴充套件,新增資料有新的欄位時,報錯,資料寫入失敗

批量寫入

批量請求顯然會大大提升寫入速率,且這個速率是可以量化的,官方建議每次批量的資料物理位元組數5-15MB是一個比較不錯的起點,注意這裡說的是物理位元組數大小。

文件計數對批量大小來說不是一個好指標,比如說,如果你每次批量索引 1000 個文件,記住下面的事實:1000 個 1 KB 大小的文件加起來是 1 MB 大,1000 個 100 KB 大小的文件加起來是 100 MB 大。

這可是完完全全不一樣的批量大小了,批量請求需要在協調節點上載入進記憶體,所以批量請求的物理大小比文件計數重要得多,從 5–15 MB 開始測試批量請求大小,緩慢增加這個數字,直到你看不到效能提升為止。

然後開始增加你的批量寫入的併發度(多執行緒等等辦法),用iostat 、 top 和 ps 等工具監控你的節點,觀察資源什麼時候達到瓶頸。如果你開始收到 EsRejectedExecutionException ,你的叢集沒辦法再繼續了:至少有一種資源到瓶頸了,或者減少併發數,或者提供更多的受限資源(比如從機械磁碟換成 SSD),或者新增更多節點。

索引和shard

es的索引,shard都會有對應的元資料,

因為es的元資料都是儲存在master節點,且元資料的更新是要hold住叢集向所有節點同步的,當es的新建欄位或者新建索引的時候,都會要獲取叢集元資料,並對元資料進行變更及同步,此時會影響叢集的響應,所以需要關注叢集的index和shard數量,

使用建議

建議如下

  1. 使用shrink和rollover api,相對生成合適的資料shard數;
  2. 根據資料量級及對應的效能需求,選擇建立index的名稱,形如:按月生成索引:test-YYYYMM,按天生成索引:test-YYYYMMDD;
  3. 控制單個shard的size,正常情況下,日誌場景,建議單個shard不大於50GB,線上業務場景,建議單個shard不超過20GB;

段合併

段合併的計算量龐大, 而且還要吃掉大量磁碟 I/O

合併在後臺定期操作,因為他們可能要很長時間才能完成,尤其是比較大的段,這個通常來說都沒問題,因為大規模段合併的概率是很小的。

如果發現merge佔用了大量的資源,可以設定:index.merge.scheduler.max_thread_count: 1 特別是機械磁碟在併發 I/O 支援方面比較差,所以我們需要降低每個索引併發訪問磁碟的執行緒數,這個設定允許 max_thread_count + 2 個執行緒同時進行磁碟操作,也就是設定為 1 允許三個執行緒,對於 SSD,你可以忽略這個設定,預設是 Math.min(3, Runtime.getRuntime().availableProcessors() / 2) ,對 SSD 來說執行的很好。

業務低峰期通過force_merge強制合併segment,降低segment的數量,減小記憶體消耗;關閉冷索引,業務需要的時候再進行開啟,如果一直不使用的索引,可以定期刪除,或者備份到hadoop叢集;

自動生成_id

當寫入端使用特定的id將資料寫入es時,es會去檢查對應的index下是否存在相同的id,這個操作會隨著文件數量的增加而消耗越來越大,所以如果業務上沒有強需求,建議使用es自動生成的id,加快寫入速率。

routing

對於資料量較大的業務查詢場景,es側一般會建立多個shard,並將shard分配到叢集中的多個例項來分攤壓力,正常情況下,一個查詢會遍歷查詢所有的shard,然後將查詢到的結果進行merge之後,再返回給查詢端。

此時,寫入的時候設定routing,可以避免每次查詢都遍歷全量shard,而是查詢的時候也指定對應的routingkey,這種情況下,es會只去查詢對應的shard,可以大幅度降低合併資料和排程全量shard的開銷。

使用alias

生產提供服務的索引,切記使用別名提供服務,而不是直接暴露索引名稱,避免後續因為業務變更或者索引資料需要reindex等情況造成業務中斷。

避免寬表

在索引中定義太多欄位是一種可能導致對映爆炸的情況,這可能導致記憶體不足錯誤和難以恢復的情況,這個問題可能比預期更常見,index.mapping.total_fields.limit ,預設值是1000

避免稀疏索引

因為索引稀疏之後,對應的相鄰文件id的delta值會很大,lucene基於文件id做delta編碼壓縮導致壓縮率降低,從而導致索引檔案增大,同時,es的keyword,陣列型別採用doc_values結構,每個文件都會佔用一定的空間,即使欄位是空值,所以稀疏索引會造成磁碟size增大,導致查詢和寫入效率降低。

最後說一句(求關注,別白嫖我)

如果這篇文章對您有所幫助,或者有所啟發的話,求一鍵三連:點贊、轉發、在看。您的支援是我堅持寫作最大的動力。

  • 作者: 博學谷狂野架構師

  • GitHub地址:GitHub地址 (有我們精心準備的130本電子書PDF)

本文由傳智教育博學谷狂野架構師教研團隊釋出。

如果本文對您有幫助,歡迎關注點贊;如果您有任何建議也可留言評論私信,您的支援是我堅持創作的動力。

轉載請註明出處!