目錄
本文主要針對的是地理數據,地理數據的特點是具有二維或三維的座標數據,且都是基於PostGIS擴展對地理數據的操作來說的。
空間索引是空間數據庫的關鍵所在,空間索引強,空間數據庫支持大規模的數據纔有意義,可以說空間索引的好壞決定了數據庫的強弱。R-tree索引經常用於地理數據,GIST索引也是PostGIS中用於地理數據的推薦索引,從PostGIS 0.6開始,便不推薦直接使用R-tree索引地理數據了,轉而推薦在GiST框架內實現的R-tree索引。那麼,PostGIS爲什麼要做出這樣的選擇呢?R-tree有什麼問題呢?GiST之於R-tree有什麼優勢呢,它們之間又有什麼區別和聯繫?
PostGIS的FAQ中有人問到了這個問題,給出的答案是:測試結果表明,兩者的性能相差不大,當然還是R-tree更快,而且在PostgreSQL中的R-tree實現有缺陷:
- 不能處理超過8k的要素,GiST可以;
- PostgreSQL中實現的R-tree不是null-safe的,如果geometry有null值,則索引構建會失敗。
GIST索引
GiST其實不是一個真正意義上的索引,它是一個索引實現模板,提供了一些api,B-tree和R-tree都可以在GiST的框架內實現。
GiST原理
GiST是一種平衡樹的數據結構,它的關鍵在於key是可以定製的,例如R-tree本身的key是整數型,而實現了R-tree的GiST的key是外包矩形(Bounding Box)。
想在GiST框架內實現一種索引,你需要做的首先就是明確key的內容,然後爲key實現四個方法,用以支持樹的插入、刪除和查詢操作。這四個方法是:
- Consistent,
- Union,
- Penalty,
- PickSplit,
R-tree索引
R樹是很常用的空間數據索引,它是樹狀數據結構。給空間數據建立R樹索引後,可以很容易的回答空間查詢的相關問題,如某點附近2千米的範圍內有哪些廁所。
R-tree原理
R-tree中的‘R’代表Rectangle(矩形),R-tree以M值爲依據計算外包矩形,將一個或多個空間要素的外包矩形作爲key進行索引,最後將外包矩形和要素構建爲一棵樹,方便根據外包矩形進行查詢,要素在樹中都是葉子節點,而外包矩形從根節點到葉子節點的直接父節點都是計算的外包矩形,且範圍逐漸細化。維基上的圖片很直觀:
GiST與R-tree並不是平行概念
從上面的概念可以看出,GiST和R-tree並不是平行的概念,準確的說,GiST並不是索引,
創建時間
創建測試表,並往裏灌2億條多邊形數據,分別創建gist索引和rtree索引:
CREATE TABLE test_idx_table (
id SERIAL8,
area DOUBLE PRECISION,
the_geom_webmercator geometry
);create index concurrently table_name_gist_idx on table_name using gist(geom);
create index concurrently table_name_rtree_idx on table_name using rtree(geom);
測試結果表明,對兩億面數據,創建R-tree索引耗時"2m 11s 49ms",而GiST索引創建時間爲“2m 12s 111ms”,兩者相差無幾。索引創建時間並不是兩者的關鍵區別。
支持的操作