空間索引是postgis中十分重要的功能,一個數據庫中如果不支持索引那幾乎是沒法使用的。postgis中空間索引通過將數據組織到搜索樹中來加快搜索速度,搜索樹可以快速遍歷以查找特定記錄。
對於空間的幾何圖形,不是通過btree索引來加速查詢,而是通過gist索引。gist索引是通過r_tree的結構來實現對空間類型數據的索引查詢,其結構類似於btree索引。
r樹介紹:https://zh.wikipedia.org/wiki/R%E6%A0%91
gist索引是怎麼工作的呢?
比如上面這個圖片,查詢和黃星相交的對象,即是圖中的紅線,gist索引不能索引幾何要素本身,而是索引幾何要素的邊界框(bouding box)。
所以在索引計算時,其實是先判斷那些邊界框和黃星所在的框相交,顯然是紅線和藍線的框,然後再進行哪些直線與黃星相交的精確計算。
使用語法:
postgis=# create index idx_t_pos_1 on t_pos using gist(pos);
CREATE INDEX
對一張數據量1000的表進行全表掃描:
postgis=# select count(*) from t_pos;
count
-------
1000
(1 row)
postgis=# explain (analyze,buffers,timing) select * from t_pos where pos && st_astext(' POINT(73.689759 3.880185)');
QUERY PLAN
-------------------------------------------------------------------------------------------------
Seq Scan on t_pos (cost=0.00..21.50 rows=1 width=36) (actual time=0.012..0.600 rows=1 loops=1)
Filter: (pos && '0101000000C9C7EE02256C52402670EB6E9E0A0F40'::geometry)
Rows Removed by Filter: 999
Buffers: shared hit=9
Planning Time: 0.231 ms
Execution Time: 0.612 ms
(6 rows)
加上索引,使用索引查詢:
postgis=# explain (analyze,buffers,timing) select * from t_pos where pos && st_astext(' POINT(73.689759 3.880185)');
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Index Scan using idx_t_pos_1 on t_pos (cost=0.14..8.16 rows=1 width=36) (actual time=0.057..0.058 rows=1 loops=1)
Index Cond: (pos && '0101000000C9C7EE02256C52402670EB6E9E0A0F40'::geometry)
Buffers: shared hit=3
Planning Time: 0.228 ms
Execution Time: 0.074 ms
(5 rows)
可以看到性能有了明顯的提升!