Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google bigquery 使用纬度和经度计算距离的性能较差_Google Bigquery_Google Cloud Platform - Fatal编程技术网

Google bigquery 使用纬度和经度计算距离的性能较差

Google bigquery 使用纬度和经度计算距离的性能较差,google-bigquery,google-cloud-platform,Google Bigquery,Google Cloud Platform,我试图从特定的位置得到2公里或更少的人口数量,为此,我用纬度和经度计算距离。在一个表中,我只有纬度和经度,在另一个表中,我有更多的字段,但也有纬度和经度 表1=488792行 表2=63003行 查询有效,运行时将处理12.3 MB 我使用的查询是: select e.lat, e.long, e.searches, count(distinct l.id) from dataset.table1 e join dataset.table2 l on 6371000*ACOS(CO

我试图从特定的位置得到2公里或更少的人口数量,为此,我用纬度和经度计算距离。在一个表中,我只有纬度和经度,在另一个表中,我有更多的字段,但也有纬度和经度

表1=488792行 表2=63003行 查询有效,运行时将处理12.3 MB

我使用的查询是:

select 
e.lat,
e.long,
e.searches,
count(distinct l.id)
from dataset.table1 e
join dataset.table2 l 
     on 6371000*ACOS(COS(3.14159265359/180*(90-e.lat)) *COS(3.14159265359/180*(90-l.lat)) +SIN(3.14159265359/180*(90-e.lat)) *SIN(3.14159265359/180*(90-l.lat)) *COS(3.14159265359/180*(e.long-l.long))) <= 2000 # way to calculate distance from lats and longs
group by e.lat,
e.long,
e.searches
但是查询没有运行,每次都需要超过15分钟,我不得不取消


有什么问题吗?

使用距离的连接谓词进行这种蛮力分析不会有好的性能。BigQuery团队正在考虑为地理空间分析添加更好的支持,即在连接谓词中使用ST_DWithin函数。同时,加入Postgres并使用PostGIS扩展可能是你最好的选择。

使用连接到距离谓词进行这种暴力分析不会有好的性能。BigQuery团队正在考虑为地理空间分析添加更好的支持,即在连接谓词中使用ST_DWithin函数。同时,进入Postgres并使用PostGIS扩展可能是最好的选择。

此查询与原始查询类似,需要2分钟:

SELECT distance, COUNT(*) FROM (
SELECT
  e.lat,
  e.long
  , 6371000*ACOS(COS(3.14159265359/180*(90-e.lat)) *COS(3.14159265359/180*(90-l.lat)) +SIN(3.14159265359/180*(90-e.lat)) *SIN(3.14159265359/180*(90-l.lat)) *COS(3.14159265359/180*(e.long-l.long))) <= 2000 distance
  , e.long-l.long longlong, e.lat-l.lat latlat
FROM
  `buoyant-history-159518.test_lat_long.table1` e
JOIN
  `buoyant-history-159518.test_lat_long.table1` l
ON 
 (COS(3.14159265359/180*(90-e.lat)) *COS(3.14159265359/180*(90-l.lat)) +SIN(3.14159265359/180*(90-e.lat)) *SIN(3.14159265359/180*(90-l.lat)) *COS(3.14159265359/180*(e.long-l.long))) <= COS(2000/6371000) + 4.5E-8
)
GROUP BY distance
为了防止浮点错误,我必须转换连接不等式:

6371000*ACOS(COS(3.14159265359/180*(90-e.lat)) *COS(3.14159265359/180*(90-l.lat)) +SIN(3.14159265359/180*(90-e.lat)) *SIN(3.14159265359/180*(90-l.lat)) *COS(3.14159265359/180*(e.long-l.long))) 
<= 2000
与此类似:

(COS(3.14159265359/180*(90-e.lat)) *COS(3.14159265359/180*(90-l.lat)) +SIN(3.14159265359/180*(90-e.lat)) *SIN(3.14159265359/180*(90-l.lat)) *COS(3.14159265359/180*(e.long-l.long))) <= COS(2000/6371000) + 4.5E-8)
<= COS(2000/6371000) + 4.5E-8
现在的问题是,我们如何才能获得比2分钟更好的表现?让我们添加一些“健全”过滤器->同一区域中的2个点之间的距离不能超过0

SELECT distance, COUNT(*) FROM (
SELECT
  e.lat,
  e.long
  , (COS(3.14159265359/180*(90-e.lat)) *COS(3.14159265359/180*(90-l.lat)) +SIN(3.14159265359/180*(90-e.lat)) *SIN(3.14159265359/180*(90-l.lat)) *COS(3.14159265359/180*(e.long-l.long))) <= COS(2000/6371000) distance
  , e.long-l.long longlong, e.lat-l.lat latlat
FROM
  `buoyant-history-159518.test_lat_long.table1` e
JOIN
  `buoyant-history-159518.test_lat_long.table1` l
ON 
 NOT (e.long=l.long AND e.lat=l.lat) 
 AND ABS(e.long-l.long) < 0.021 #sanity JOIN check
 AND ABS(e.lat-l.lat) < 0.018 #sanity JOIN check
)
GROUP BY distance
我们得到了非常相似的结果,但只需12秒,而不是2分钟


我无法优化您的精确查询,因为您的示例表没有相同的数字、行或列,但在进行完全交叉联接之前,请尝试应用这些健全联接检查。

此查询与原始查询类似,需要2分钟:

SELECT distance, COUNT(*) FROM (
SELECT
  e.lat,
  e.long
  , 6371000*ACOS(COS(3.14159265359/180*(90-e.lat)) *COS(3.14159265359/180*(90-l.lat)) +SIN(3.14159265359/180*(90-e.lat)) *SIN(3.14159265359/180*(90-l.lat)) *COS(3.14159265359/180*(e.long-l.long))) <= 2000 distance
  , e.long-l.long longlong, e.lat-l.lat latlat
FROM
  `buoyant-history-159518.test_lat_long.table1` e
JOIN
  `buoyant-history-159518.test_lat_long.table1` l
ON 
 (COS(3.14159265359/180*(90-e.lat)) *COS(3.14159265359/180*(90-l.lat)) +SIN(3.14159265359/180*(90-e.lat)) *SIN(3.14159265359/180*(90-l.lat)) *COS(3.14159265359/180*(e.long-l.long))) <= COS(2000/6371000) + 4.5E-8
)
GROUP BY distance
为了防止浮点错误,我必须转换连接不等式:

6371000*ACOS(COS(3.14159265359/180*(90-e.lat)) *COS(3.14159265359/180*(90-l.lat)) +SIN(3.14159265359/180*(90-e.lat)) *SIN(3.14159265359/180*(90-l.lat)) *COS(3.14159265359/180*(e.long-l.long))) 
<= 2000
与此类似:

(COS(3.14159265359/180*(90-e.lat)) *COS(3.14159265359/180*(90-l.lat)) +SIN(3.14159265359/180*(90-e.lat)) *SIN(3.14159265359/180*(90-l.lat)) *COS(3.14159265359/180*(e.long-l.long))) <= COS(2000/6371000) + 4.5E-8)
<= COS(2000/6371000) + 4.5E-8
现在的问题是,我们如何才能获得比2分钟更好的表现?让我们添加一些“健全”过滤器->同一区域中的2个点之间的距离不能超过0

SELECT distance, COUNT(*) FROM (
SELECT
  e.lat,
  e.long
  , (COS(3.14159265359/180*(90-e.lat)) *COS(3.14159265359/180*(90-l.lat)) +SIN(3.14159265359/180*(90-e.lat)) *SIN(3.14159265359/180*(90-l.lat)) *COS(3.14159265359/180*(e.long-l.long))) <= COS(2000/6371000) distance
  , e.long-l.long longlong, e.lat-l.lat latlat
FROM
  `buoyant-history-159518.test_lat_long.table1` e
JOIN
  `buoyant-history-159518.test_lat_long.table1` l
ON 
 NOT (e.long=l.long AND e.lat=l.lat) 
 AND ABS(e.long-l.long) < 0.021 #sanity JOIN check
 AND ABS(e.lat-l.lat) < 0.018 #sanity JOIN check
)
GROUP BY distance
我们得到了非常相似的结果,但只需12秒,而不是2分钟


我无法优化您的精确查询,因为您的示例表没有相同的数目、行或列,但在进行完全交叉连接之前,请尝试应用这些健全连接检查。

完整表扫描可能是问题所在。你需要很好的索引,看起来你有一个非常复杂的连接。任何或所有这些都可能是原因。你能提供一个样本数据集吗?我很想优化这个查询,但我需要一个合适的测试床@FelipeHoffa,我怎样才能发送给你?谢谢@菲利佩霍法,我在那里分享。浮力-history-159518:可能是测试平台扫描的问题。你需要很好的索引,看起来你有一个非常复杂的连接。任何或所有这些都可能是原因。你能提供一个样本数据集吗?我很想优化这个查询,但我需要一个合适的测试床@FelipeHoffa,我怎样才能发送给你?谢谢@菲利佩霍法,我在那里分享。Flougant-history-159518:test_lat_long作为对BigQuery中的地理空间分析感兴趣的人,我如何获得这些功能的可用性更新?作为对BigQuery中的地理空间分析感兴趣的人,我如何获得这些功能的可用性更新?非常感谢,@Felipe!为了满足我们在生产数据集中的需要,我对查询做了一点修改,但是您的技巧使它能够工作!非常感谢你,菲利佩!为了满足我们在生产数据集中的需要,我对查询做了一点修改,但是您的技巧使它能够工作!