我需要建议,因为我不够好。PostgreSQL如何创建可扩展的基于位置的查询
我在AWS(亚马逊网络服务)上运行的PostgreSQL中有一个数据库。 我有一个表“user_location”,其中存储每个用户的位置,现在有超过300万行。
我有经常运行下面的查询,以便脚本来看看两个用户都在附近:
SELECT
UL.id AS id,
UL.user_id AS user_id,
ST_X(UL.location::geometry) AS lat,
ST_Y(UL.location::geometry) AS lng,
UL.datetime AS datetime
FROM
public.user_location AS UL
WHERE
UL.user_id <> 1234567890 AND
'1890-10-31 03:00:00 +00:00' - UL.datetime <= interval '1' minute AND
'1890-10-31 03:00:00 +00:00' >= UL.datetime AND
ST_DWithin(UL.location, ST_GeogFromText('POINT(54 -1)'), 5000)
ORDER BY
UL.datetime DESC;
这个问题似乎是半径,查询的执行时间通过增加呈指数级增长因为它需要检查更多行。
我需要一个可扩展的解决方案,通过增加给定位置周围的半径,执行时间几乎相同。我需要在日期时间之前和查询中的半径之后使用“水平切割”数据,我该怎么办?
我也EXPLAIN分析哪些是输出:
"Sort (cost=389.72..389.73 rows=3 width=52) (actual time=136848.985..136848.985 rows=0 loops=1)"
" Sort Key: datetime"
" Sort Method: quicksort Memory: 25kB"
" -> Bitmap Heap Scan on user_location ul (cost=11.00..389.70 rows=3 width=52) (actual time=136848.976..136848.976 rows=0 loops=1)"
" Recheck Cond: (location && '0101000020E6100000C182458F29494B4095E0C3DB39E3F3BF'::geography)"
" Filter: ((user_id <> 1234567890) AND ('1890-10-31 03:00:00 +00:00'::timestamp with time zone >= datetime) AND (('1890-10-31 03:00:00 +00:00'::timestamp with time zone - datetime) <= '00:01:00'::interval minute) AND ('0101000020E6100000C182458F29494B4095E0C3DB39E3F3BF'::geography && _st_expand(location, 5000::double precision)) AND _st_dwithin(location, '0101000020E6100000C182458F29494B4095E0C3DB39E3F3BF'::geography, 5000::double precision, true))"
" -> Bitmap Index Scan on users_locations_gix (cost=0.00..11.00 rows=91 width=0) (actual time=4463.249..4463.249 rows=165622 loops=1)"
" Index Cond: (location && '0101000020E6100000C182458F29494B4095E0C3DB39E3F3BF'::geography)"
"Total runtime: 136849.591 ms"
提前感谢! 干杯
谢谢@cmd!我认为,通过“...和...之间”,查询变得可靠。我创建了一个索引'(datetime DESC)',但这需要时间。我不知道有多少个条目取决于用户的数量,所以它应该多于或少于1000个条目。 – angelst00ne