postgresql查询需要永远的时间
我有下面的问题,这需要永远(几天),如果你能提供任何帮助,如何改善它将是伟大的 该服务器有2个xeon e5-2630 v3 CPU(8核,每个16线程),带有128 GB RAM和SSD磁盘,postgres 11postgresql查询需要永远的时间,postgresql,postgis,Postgresql,Postgis,我有下面的问题,这需要永远(几天),如果你能提供任何帮助,如何改善它将是伟大的 该服务器有2个xeon e5-2630 v3 CPU(8核,每个16线程),带有128 GB RAM和SSD磁盘,postgres 11 SELECT distinct on (location_signals.p_key) ooh_data.*, location_signals."Lat" AS did_lat, location_signals."Lon" As did_lo
SELECT distinct on (location_signals.p_key) ooh_data.*,
location_signals."Lat" AS did_lat, location_signals."Lon" As did_lon, location_signals.device,
location_signals.timestamp AS did_timestamp, location_signals.p_key AS did_p_key
FROM ooh_data ,
location_signals
WHERE ST_DWithin(
ST_SetSRID(ST_MakePoint(ooh_data.offset_lon, ooh_data.offset_lat), 4326)::geography,
ST_SetSRID(ST_MakePoint(location_signals."Lon", location_signals."Lat"), 4326)::geography,
100
)
ORDER BY location_signals.p_key;
位置信号有3亿条记录,ooh数据有6000条记录
这里有一个解释,它极大地限制了选择:
explain analyse SELECT distinct on (location_signals.p_key) ooh_data.*
FROM ooh_data ,
location_signals
WHERE ST_DWithin(
ST_SetSRID(ST_MakePoint(ooh_data.offset_lon, ooh_data.offset_lat), 4326)::geography,
ST_SetSRID(ST_MakePoint(location_signals."Lon", location_signals."Lat"), 4326)::geography,
100
)
AND ooh_data.p_key > 5700
AND location_signals.timestamp > '2019-05-31 23:57:00'
ORDER BY location_signals.p_key;
结果:
QUERY PLAN
Unique (cost=100551.80..100551.80 rows=1 width=84) (actual time=305.190..305.193 rows=2 loops=1)
-> Sort (cost=100551.80..100551.80 rows=1 width=84) (actual time=305.189..305.190 rows=3 loops=1)
Sort Key: location_signals.p_key
Sort Method: quicksort Memory: 25kB
-> Gather (cost=1029.18..100551.79 rows=1 width=84) (actual time=305.180..310.644 rows=3 loops=1)
Workers Planned: 1
Workers Launched: 1
-> Nested Loop (cost=29.18..99551.69 rows=1 width=84) (actual time=195.851..277.511 rows=2 loops=2)
Join Filter: (((st_setsrid(st_makepoint(ooh_data.offset_lon, ooh_data.offset_lat), 4326))::geography && _st_expand((st_setsrid(st_makepoint(location_signals."Lon", location_signals."Lat"), 4326))::geography, '100'::double precision)) AND ((st_setsrid(st_makepoint(location_signals."Lon", location_signals."Lat"), 4326))::geography && _st_expand((st_setsrid(st_makepoint(ooh_data.offset_lon, ooh_data.offset_lat), 4326))::geography, '100'::double precision)) AND _st_dwithin((st_setsrid(st_makepoint(ooh_data.offset_lon, ooh_data.offset_lat), 4326))::geography, (st_setsrid(st_makepoint(location_signals."Lon", location_signals."Lat"), 4326))::geography, '100'::double precision, true))
Rows Removed by Join Filter: 139156
-> Parallel Bitmap Heap Scan on location_signals (cost=28.89..2814.14 rows=1482 width=24) (actual time=1.144..10.886 rows=1288 loops=2)
Recheck Cond: ("timestamp" > '2019-05-31 23:57:00'::timestamp without time zone)
Heap Blocks: exact=1396
-> Bitmap Index Scan on idx_timestamp (cost=0.00..28.27 rows=2519 width=0) (actual time=1.355..1.356 rows=2577 loops=1)
Index Cond: ("timestamp" > '2019-05-31 23:57:00'::timestamp without time zone)
-> Index Scan using ooh_data_pkey on ooh_data (cost=0.28..5.35 rows=107 width=76) (actual time=0.004..0.025 rows=108 loops=2577)
Index Cond: (p_key > 5700)
Planning Time: 0.424 ms
Execution Time: 310.738 ms
感谢您的帮助,谢谢我将首先在两个表中创建地理列,并在其中保存点。然后将空间索引添加到两个表中: 请使用这些索引点进行连接,这样会更快
没有索引,它是完全交叉连接的,而且非常昂贵。有了索引,它应该工作得更快,尽管对于单个框来说可能仍然是一个繁重的查询。我将首先在两个表中创建地理列,并将点保存在那里。然后将空间索引添加到两个表中: 请使用这些索引点进行连接,这样会更快
没有索引,它是完全交叉连接的,而且非常昂贵。有了索引,它应该可以更快地工作,尽管对于单个框来说可能仍然是一个繁重的查询。减少您的查询,直到explain可以给您一个答案,然后找出您添加的一件事打破它。需要注意的是,除非数据被正确索引,否则连接300毫米记录将花费永远的时间。您正在执行的查询可能无法使用索引,可能必须执行300MM*6K查询,或者换句话说,1.8万亿次比较。谢谢,我会尝试一下……您有其他建议吗?我们建立了一个逻辑,每个单独的ooh_数据输入和查询都会用到这个逻辑,但我认为实际上是一样的,我们希望通过1次查询而不是1.8万亿次查询,这可能会更快。通过预处理
ooh_data
表并为ST_setrid(ST_MakePoint(ooh_data.offset_lon,ooh_data.offset_lat),4326创建a列,我们可能能够节省一些计算:geography
。然后在子查询中使用新列。这取决于你如何使用PostGIS。有时它能够理解你说的话并使用索引,但有时这是一个很大的否定。我关心的是,你不是在加入,你只是从两个表中选择一个WHERE
。减少你的查询,直到explain可以给你一个答案,然后找出你添加的一件事打破它。需要注意的是,加入300MM记录将花费永远的时间,除非数据被正确索引。您正在执行的查询可能无法使用索引,可能必须执行300MM*6K查询,或者换句话说,1.8万亿次比较。谢谢,我会尝试一下……您有其他建议吗?我们建立了一个逻辑,每个单独的ooh_数据输入和查询都会用到这个逻辑,但我认为实际上是一样的,我们希望通过1次查询而不是1.8万亿次查询,这可能会更快。通过预处理ooh_data
表并为ST_setrid(ST_MakePoint(ooh_data.offset_lon,ooh_data.offset_lat),4326创建a列,我们可能能够节省一些计算:geography
。然后在子查询中使用新列。这取决于你如何使用PostGIS。有时它能够理解你说的话并使用索引,但有时这是一个很大的否定。我关心的是,您没有加入,您只是从两个表中选择一个WHERE
。