PostGreSQL不一樣索引類型(btree & hash)的性能問題

在關係型數據庫調優中,查詢語句涉及到的索引類型是不得不考慮的一個問題。不一樣的類型的索引可能會適用不一樣類型的業務場景。這裏咱們所說的索引類型指的是訪問方法(Access Method),至於從其餘維度區分索引(Index)這裏暫不做考慮。sql

PostGreSQL數據庫默認的索引訪問方法是btree,其餘的數據庫如Oracle默認也是btree。那麼btree究竟是何方神聖呢?若是想要深刻理解btree的運行原理,須要瞭解一下數據結構相關的知識,特別是樹形數據結構。btree運用了b+ 樹數據結構,其能夠有效節省IO操做,在查詢時能夠提供查詢效率。數據庫


Screen Shot 2020-09-27 at 23.25.15.png

    咱們沿用以前文章用過的查詢語句來作測試,其中sort_test表有500萬行數據。表建立SQL和查詢語句以下:數據結構

CREATE TABLE public.sort_test(    id bigint NOT NULL,    salary numeric NOT NULL,    CONSTRAINT sort_test_pkey PRIMARY KEY (id))
TABLESPACE pg_default;

explain analyze select * from public."sort_test" where salary = 101;

 那麼執行計劃的細節以下圖所示:app

Screen Shot 2020-09-27 at 23.26.56.png

下面將在一樣的表字段上,刪除原來的索引,添加相應的hash索引。添加語句爲:
ide

CREATE INDEX index_sort_test_salary_hash    ON public.sort_test USING hash    (salary)    TABLESPACE pg_default;

添加完以後,以下圖所示:性能

Screen Shot 2020-09-27 at 23.27.51.png

一樣的查詢語句的執行計劃是怎樣的呢?以下圖:測試

Screen Shot 2020-09-27 at 23.28.20.png


能夠發現0.757 ms  vs. 0.022 ms仍是有數量級的差異,在這種狀況下,hash索引的效率比btree的效率要高不少。因爲hash索引結構的特殊性,其檢索效率很是高,能夠一步到位。而通常使用的B-tree索引須要從根節點->枝節點->頁節點。因此從工做模式上看,hash索引的效率要比btree索引要高。
spa

可是咱們你們都懂的,事務都有兩面性,hash索引有必定的限制和弊端,要否則這些經常使用的數據庫如Oracle, MySQL,PostGreSQL等也不會將btree access method設置爲默認選項了。具體有以下2點限制:3d

  • Hash索引只能知足"=","IN"等,等值查詢,不能使用範圍查詢。code

  • 在使用部分索引鍵查詢的時候,hash索引將不起做用。


因此在應用不一樣的索引類型時,要充分考慮具體的業務場景和實際狀況,才能獲得更優解。

你們也能夠掃描並關注以下公衆號「TimTest」,會有更多性能測試相關內容分享。

qrcode_for_gh_39009e949117_258-1.jpg