我正在将 SQLite 数据库结构迁移到 PostgreSQL。该 SQLite 数据库使用带有空间索引的 R*Tree 模块来进行快速 3D 边界框搜索。
我没有空间索引和 PostgreSQL 的经验。
我已阅读有关 PostgreSQL GiST 索引的文档,这似乎表明这可以实现类似的功能。但我一直无法找到如何将此功能应用于 3D 边界框检查。
我想不知何故 <@ operator with box and point should do the trick. Can someone elaborate if this intuition is right and provide a small example of how to define a table with spatial 3D data and a query that does a bounding box check?
这是示例数据和我正在寻找的查询思路:
id | x | y | z |
---|---|---|---|
1 | 0 | 1 | 2 |
2 | 4 | 5 | 6 |
SELECT id FROM table WHERE x >= 0 AND x <= 2 AND y >= 0 AND y <= 2 AND z >= 0 AND z <= 2
使用 PostGIS,您可以将索引设置为任何其他要点索引 - 默认运算符类根据类型应用。 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, random()*180 x,
90-random()*180 y,
50-random()*100 z,
50-random()*100 t)b(n1,x,y,z,t);
insert into business(business_name,x,y,z,t) values
('business_d0',0,0,0,0),
('business_d1',1,0,0,0),
('business_d2',0,1,0,0),
('business_d3',0,0,1,0),
('business_d4',0,0,0,1);
设置索引。默认运算符类将仅使用每个几何图形的两个维度来构建 r 树,因此您需要指定
gist_geometry_ops_nd
运算符类来处理 n 维几何图形的所有维度:
drop index if exists geom_idx;
create index geom_idx on business using gist(geom gist_geometry_ops_nd);
测试操作,显示索引使用:选择距离参考点最近的 5 个点:
prepare postgis_based as
select id,business_name,x,y,z,t
,(select geom from business where id=42)<<->>geom 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.376..1.411 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.007..0.008 rows=1 loops=1)
Index Cond: (id = 42)
-> Index Scan using geom_idx on business (cost=0.28..13420.38 rows=100005 width=73) (actual time=0.375..1.408 rows=7 loops=1)
Order By: (geom <<->> $0)
Planning Time: 0.357 ms
Execution Time: 1.477 ms
id | 企业名称 | x | y | z | t | 距离 |
---|---|---|---|---|---|---|
42 | 业务_42 | 135.913060823458 | 7.7997970642875 | 2.93153014852416 | 13.8754985934873 | 0 |
10212 | 业务_10212 | 138.015417820462 | 6.16780328827525 | 6.99214194619289 | 17.9070448007494 | 6.310724334056296 |
39781 | 业务_39781 | 135.825537405277 | 10.1567444370512 | 1.08794511732091 | 19.9058199716022 | 6.732491586131694 |
78354 | 业务_78354 | 137.145666026389 | 12.8802423990292 | 5.95771554931872 | 17.565112372697 | 7.078226353070906 |
74004 | 业务_74004 | 131.450844772993 | 7.42647416532242 | -1.66828745462648 | 17.208767597593 | 7.233238991206186 |
43296 | 业务_43296 | 139.082823062846 | 8.30873695673203 | 3.44753032284635 | 20.5087372769281 | 7.387321847582334 |
95119 | 业务_95119 | 130.772860227918 | 4.31568006546163 | 2.77471451324465 | 18.0819978648418 | 7.5019971132540055 |