新零售空间数据库实践一例 - PostGIS 点面叠加视觉判断输出

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

标签

PostgreSQL , 点面视觉输出 , subquery , nestloop join , 空间索引 , gist


背景

在新零售、快递等行业,有大量的点数据(例如包裹位置、快递员位置、仓库位置等),同时有大量的面数据(如小区,商圈,写字楼等)。

如何判断实时的正在配送的包裹落在哪个面呢?并且将之联系起来。

这个从视觉角度来思考,非常简单。

例如有一个地图,将其划分为若干个面(例如前面提到的小区)。

pic

然后有一些小点,这些是POINT数据。

pic

我们从图上一眼就能看出每个点落在哪个小区(面)里面。

在数据库中,这可能是两份数据(一份为点,一份为面)。输出的实际上是点+面(ID)的数据。

怎么做到高效的输出呢?

DEMO

搜索某些订单,当前处于哪个面。这是非常典型的点面判断需求。

接下来的例子,有25万个面,查询若干笔订单属于哪个面。

1、创建、生成静态的面数据(通常面的数据是静态的,例如小区,商圈,大楼,仓库覆盖范围等)

postgres=# create table t2(id int, pos box);  
CREATE TABLE  
  
-- 在(0,0)到(500,500)的平面上,划分成251001个正方形的小面。  
  
postgres=# do language plpgsql $$    
declare  
x int;  
y int;  
begin  
for x in 0..500 loop  
for y in 0..500 loop   
  insert into t2 values (x+y, box(point(x,y),point(x+1,y+1)));  
end loop;  
end loop;  
end;  
$$;  
DO  
  
postgres=# select count(*) from t2;  
 count    
--------  
 251001  
(1 row)  

创建空间索引

postgres=# create index idx_t2 on t2 using gist(pos);
CREATE INDEX

2、创建、生成点的数据。

postgres=# create table t1(id int, pos point);  
CREATE TABLE  
-- 在(0,0),(500,500)的平面上,生成10000个随机的点  
  
postgres=# insert into t1 select id, point(random()*500, random()*500) from generate_series(1,10000) t(id);  
INSERT 0 10000  

3、查询每个点,属于哪个面。

方法1,JOIN

postgres=# explain analyze select t1.*,t2.* from t1 join t2 on (t2.pos @> box(t1.pos, t1.pos));  
                                                       QUERY PLAN                                                         
------------------------------------------------------------------------------------------------------------------------  
 Nested Loop  (cost=0.29..73322.20 rows=2510010 width=56) (actual time=0.094..1191.076 rows=10000 loops=1)  
   ->  Seq Scan on t1  (cost=0.00..116.00 rows=10000 width=20) (actual time=0.020..1.047 rows=10000 loops=1)  
   ->  Index Scan using idx_t2 on t2  (cost=0.29..4.81 rows=251 width=36) (actual time=0.039..0.118 rows=1 loops=10000)  
         Index Cond: (pos @> box(t1.pos, t1.pos))  
 Planning time: 0.102 ms  
 Execution time: 1191.619 ms  
(6 rows)  

方法2,SUBQUERY

postgres=# explain analyze select t1.*, (select t2 from t2 where t2.pos @> box(t1.pos,t1.pos) limit 1) from t1;  
                                                            QUERY PLAN                                                              
----------------------------------------------------------------------------------------------------------------------------------  
 Seq Scan on t1  (cost=0.00..13706.74 rows=10000 width=52) (actual time=0.077..427.466 rows=10000 loops=1)  
   SubPlan 1  
     ->  Limit  (cost=0.29..1.36 rows=1 width=60) (actual time=0.042..0.042 rows=1 loops=10000)  
           ->  Index Scan using idx_t2 on t2  (cost=0.29..269.88 rows=251 width=60) (actual time=0.042..0.042 rows=1 loops=10000)  
                 Index Cond: (pos @> box(t1.pos, t1.pos))  
 Planning time: 0.080 ms  
 Execution time: 427.942 ms  
(7 rows)  

如果是1000笔订单,返回差不多40毫秒

postgres=# explain (analyze,verbose,timing,costs,buffers) select t1.*, (select t2 from t2 where t2.pos @> box(t1.pos,t1.pos) limit 1) from t1 limit 1000;
                                                                  QUERY PLAN                                                                  
----------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..1370.67 rows=1000 width=52) (actual time=0.069..39.754 rows=1000 loops=1)
   Output: t1.id, t1.pos, ((SubPlan 1))
   Buffers: shared hit=3002
   ->  Seq Scan on public.t1  (cost=0.00..13706.74 rows=10000 width=52) (actual time=0.069..39.658 rows=1000 loops=1)
         Output: t1.id, t1.pos, (SubPlan 1)
         Buffers: shared hit=3002
         SubPlan 1
           ->  Limit  (cost=0.29..1.36 rows=1 width=60) (actual time=0.039..0.039 rows=1 loops=1000)
                 Output: t2.*
                 Buffers: shared hit=3000
                 ->  Index Scan using idx_t2 on public.t2  (cost=0.29..269.88 rows=251 width=60) (actual time=0.039..0.039 rows=1 loops=1000)
                       Output: t2.*
                       Index Cond: (t2.pos @> box(t1.pos, t1.pos))
                       Buffers: shared hit=3000
 Planning time: 0.066 ms
 Execution time: 39.830 ms
(16 rows)

因为@>暂时不支持hash join,因此subquery更优一些。

本文没有用到PostGIS空间数据库插件,而是使用了内置的平面几何类型,用于演示。

真实场景请使用PostGIS。

http://postgis.net/

例如

select  t1.*, (select t2 from t2 where ST_Within(t1.geom, t2.geom) limit 1) from t1;

小结

点面判断在GIS信息崛起的今天,在越来越多的企业中成为了非常常见的需求,比如文中提到的。

PostgreSQL在空间数据库领域有非常丰富的应用,从科研、军工、商业到民用,无处不在。

结合空间索引,BRIN索引实现空间数据的高效率检索是很轻松的事情。

相关文章
|
2月前
|
存储 监控 安全
360 企业安全浏览器基于阿里云数据库 SelectDB 版内核 Apache Doris 的数据架构升级实践
为了提供更好的日志数据服务,360 企业安全浏览器设计了统一运维管理平台,并引入 Apache Doris 替代了 Elasticsearch,实现日志检索与报表分析架构的统一,同时依赖 Doris 优异性能,聚合分析效率呈数量级提升、存储成本下降 60%....为日志数据的可视化和价值发挥提供了坚实的基础。
360 企业安全浏览器基于阿里云数据库 SelectDB 版内核 Apache Doris 的数据架构升级实践
|
2月前
|
安全 Java 数据库
后端进阶之路——万字总结Spring Security与数据库集成实践(五)
后端进阶之路——万字总结Spring Security与数据库集成实践(五)
|
3月前
|
存储 SQL Cloud Native
深入了解云原生数据库CockroachDB的概念与实践
作为一种全球领先的分布式SQL数据库,CockroachDB以其高可用性、强一致性和灵活性等特点备受关注。本文将深入探讨CockroachDB的概念、设计思想以及实践应用,并结合实例演示其在云原生环境下的优越表现。
|
3月前
|
Cloud Native 关系型数据库 大数据
CockroachDB:云原生数据库的新概念与实践
本文将介绍CockroachDB,一种先进的云原生数据库,它具备分布式、强一致性和高可用性等特点。我们将探讨CockroachDB的基本原理、架构设计以及在实际应用中的种种优势和挑战。
|
7天前
|
SQL 监控 数据库
数据库管理与电脑监控软件:SQL代码优化与实践
本文探讨了如何优化数据库管理和使用电脑监控软件以提升效率。通过SQL代码优化,如使用索引和调整查询语句,能有效提高数据库性能。同时,合理设计数据库结构,如数据表划分和规范化,也能增强管理效率。此外,利用Python脚本自动化收集系统性能数据,并实时提交至网站,可实现对电脑监控的实时性和有效性。这些方法能提升信息系统稳定性和可靠性,满足用户需求。
32 0
|
2月前
|
缓存 监控 关系型数据库
构建高效的数据库应用:Python 实践
在当今数据驱动的世界中,构建高效的数据库应用程序对于企业和个人来说至关重要。Python 作为一种强大的编程语言,提供了丰富的数据库工具和库,使得开发人员能够轻松地构建高效、可靠的数据库应用程序。在本文中,我们将探讨一些关键的技术和最佳实践,以帮助你构建高效的数据库应用程序。
|
2月前
|
敏捷开发 弹性计算 架构师
浅谈微服务架构下的数据库设计与实践
在当今快速发展的软件工程领域,微服务架构因其高度的模块化和灵活性而受到广泛欢迎。然而,随之而来的是对数据库设计和管理提出了新的挑战。本文将探讨在微服务架构下,如何有效地设计和实践数据库以支持服务的独立性、数据的一致性和系统的扩展性。我们将从微服务的数据库隔离策略谈起,深入分析数据库的分库分表、事务管理、数据一致性解决方案等关键技术,并通过实例说明如何在实际项目中应用这些原则和技术。本文旨在为软件开发者和架构师提供一份指南,帮助他们在微服务架构的环境下,更好地进行数据库设计和管理。
204 1
|
3月前
|
SQL 监控 关系型数据库
解密SQL性能异常事件及阿里云数据库的性能调优实践
作为开发者想必都知道数据库是现代应用的核心组件之一,而且在当今互联网时代之下,SQL查询的性能直接影响系统的整体性能,它的性能对于系统的稳定性和响应速度至关重要。那么本文就来讨论一下SQL性能异常的排查和优化方法,包括我个人印象深刻的SQL性能异常事件,以及分享一下使用阿里云数据库产品/工具进行SQL性能调优的经验和心得体会。
84 1
解密SQL性能异常事件及阿里云数据库的性能调优实践
|
3月前
|
SQL 存储 监控
公司内部电脑监控软件的数据库管理:SQL代码实践
随着科技的飞速发展,公司内部电脑监控软件在保障信息安全和提高员工生产效率方面发挥着重要作用。本文将深入探讨监控软件的数据库管理,并通过SQL代码实践展示其操作和优化方法。
300 0
|
4月前
|
SQL BI Apache
奇富科技基于阿里云数据库 SelectDB 版内核 Apache Doris 的统一 OLAP 场景探索实践
Apache Doris 作为整体 OLAP 场景,助力奇富科技信贷科技服务平台优化,使得报表分析场景 SLA 达标率提升至 99% 以上,平均查询耗时降低 50%,为营销活动、广告投放等提供强有力的数据支持。
奇富科技基于阿里云数据库 SelectDB 版内核 Apache Doris 的统一 OLAP 场景探索实践