对于PostGIS,您可以设置一个高达4D的基于R-Tree的索引作为任何其他GIST索引.Demo at db<>fiddle:
设置包含示例的表格:
create extension postgis;
create table business(
id int generated by default as identity primary key,
business_name text,
x numeric, y numeric, z numeric, t numeric,
geom geometry(PointZM,4326) generated always as
(st_setsrid(st_makepoint(x,y,z,t),4326)) stored);
select setseed(.4);
insert into business (business_name,x,y,z,t)
select 'business_'||n, x, y, z, t
from generate_series(1,1e5,1)a(n),
lateral(select n AS n1,
180-random()*360 x,
90 -random()*180 y,
50 -random()*100 z,
50 -random()*100 t)b;
设置索引.默认运算符类将仅使用每个几何图形的两个维度来构建r-树,因此您需要指定gist_geometry_ops_nd
个运算符类来处理n维几何图形的所有维度:
create index geom_idx on business using gist(geom gist_geometry_ops_nd);
一种测试操作,显示索引用途: Select 最接近参考点的7个点:
prepare postgis_based as
select id,business_name,x,y,z,t
,(select geom from business where id=42)<<->>geom AS distance
from business
order by distance
limit 7;
explain analyze execute postgis_based;
execute postgis_based;
QUERY PLAN
Limit (cost=8.59..9.53 rows=7 width=73) (actual time=0.428..1.624 rows=7 loops=1)
InitPlan 1 (returns $0)
-> Index Scan using business_pkey on business business_1 (cost=0.29..8.31 rows=1 width=48) (actual time=0.008..0.008 rows=1 loops=1)
Index Cond: (id = 42)
-> Index Scan using geom_idx on business (cost=0.28..13468.38 rows=100005 width=73) (actual time=0.427..1.622 rows=7 loops=1)
Order By: (geom <<->> $0)
Planning Time: 0.351 ms
Execution Time: 1.689 ms
id |
business_name |
x |
y |
z |
t |
distance |
42 |
business_42 |
-91.8261216469166 |
7.7997970642875 |
2.93153014852416 |
13.8754985934873 |
0 |
39781 |
business_39781 |
-91.651074810554 |
10.1567444370512 |
1.08794511732091 |
19.9058199716022 |
6.734198096546056 |
10212 |
business_10212 |
-96.0308356409243 |
6.16780328827525 |
6.99214194619289 |
17.9070448007494 |
7.285942385786669 |
78354 |
business_78354 |
-94.2913320527778 |
12.8802423990292 |
5.95771554931872 |
17.565112372697 |
7.393188423419308 |
82772 |
business_82772 |
-90.3963886636943 |
13.9114309111029 |
-2.37759157752899 |
15.9845495479146 |
8.487112236283533 |
47097 |
business_47097 |
-93.041286078567 |
14.2177864450063 |
-1.89386518525991 |
11.233109282625 |
8.540133118659915 |
94516 |
business_94516 |
-87.3058458168426 |
1.38796268779309 |
1.78446589911467 |
18.3034143744421 |
9.08111822448362 |
如果在使用默认索引设置时将x
和y
置零,而只填充z
和t
,则可以为observe slow sequential scans kicking in,这表示只使用了前两个维度来构建树,因此在该场景中没有帮助.一旦你切换到gist_geometry_ops_nd
,你就开始得到quick index scans.