之前做多字段索引測試的時候發現一個奇怪的現象,btree-gin提供的gin索引在處理1個比較操作的範圍查詢時性能還行,但處理有2個比較操作的範圍查詢時性能就很糟糕了。下面是例子。
測試環境在一個PC的虛拟機上
主控端
- CPU:AMD Athlon II X4 640 3.0GHz
- MEM:6G
- OS:Win7 64bit
- 虛拟機所在存儲:Apacer A S510S 128GB
虛拟機
- CPU:4 core
- MEM: 2G
- OS:CentOS release 6.5 (Final)
- PostgreSQL:9.4.2(shared_buffers = 128MB,其它都是預設值)
因為在構造資料時,c1的最大值就是100,是以上述兩個查詢比對的資料是完全相同的,但結果卻相差很大。
建一個對等的btree(c1,c2)索引,然後作個比較。
btree在處理比較查詢時效率明顯比btree-gin好的多。
在gin處理"c1>97 and c1<=100"時,将其分解為兩個部分比對,"c1>97"和"c1<=100",然後再把它們的結果通過bitmap與的邏輯取交集。 由于"c1<=100"比對了所有記錄,也就要為所有記錄做bitmap與操作,是以效率很低。 btree索引則不同,btree了解比較操作符的含義,是以做了優化,通過一個(97,100]的很窄的範圍掃描就能搞定。
在這次測試中還發現一個問題,走btree-gin索引的執行計劃的代價估計值過小,嚴重偏離實際,是以如果同時定義了btree-gin索引和btree索引,優化器是一定會選擇btree-gin的。