为了找到特定IP地址的国家/地区,我使用的是Maxmind IP地址数据库。我已经下载了数据库并将其导入到Google BigQuery中,因此可以对其进行查询。在一个单独的表中,我从系统中的某些事件捕获IP地址。我现在想加入这两个数据源。
Maxmind数据库中的列如下:
我的事件表中的列是:
如此处(https://dev.maxmind.com/geoip/legacy/csv/所述,有一种方法可以获取IP地址的整数表示形式,因此我可以使用它来查询IP地址并检索country_code或country_name。
我现在构造了以下查询:
SELECT
p.*,
g.country_code AS country_code
FROM
`dev.event_v1` p
INNER JOIN
`dev.geo_ip_countries` g
ON
SAFE_CAST(SPLIT(p.ip_address, ".")[OFFSET(0)] AS NUMERIC)*16777216 +
SAFE_CAST(SPLIT(p.ip_address, ".")[OFFSET(1)] AS NUMERIC)*65536 +
SAFE_CAST(SPLIT(p.ip_address, ".")[OFFSET(2)] AS NUMERIC)*256 +
SAFE_CAST(SPLIT(p.ip_address, ".")[OFFSET(3)] AS NUMERIC)
BETWEEN
SAFE_CAST(g.start_ip_num AS INT64)
AND
SAFE_CAST(g.end_ip_num AS INT64)
LIMIT 100
但是,这在使用限制时有效,它不适用于构造视图。
两个问题: 1.有没有一种方法可以简化查询 2.当我尝试返回较大的结果集时,Google BigQuery引发错误:
Error: Query exceeded resource limits. 28099.974050246612 CPU seconds were used, and this query must use less than 5600.0 CPU seconds.
感谢您的帮助!
解决方案 将查询重写为以下内容可以解决资源限制问题:
SELECT
p.*,
g.country_code
FROM
`dev.event_v1` p
INNER JOIN
`dev.geo_ip_countries` g
ON
NET.IP_TRUNC(NET.SAFE_IP_FROM_STRING(p.ip_address),16) = NET.IP_TRUNC(NET.SAFE_IP_FROM_STRING(g.start_ip_range),16)
WHERE
NET.SAFE_IP_FROM_STRING(p.ip_address)
BETWEEN
NET.SAFE_IP_FROM_STRING(g.start_ip_range)
AND
NET.SAFE_IP_FROM_STRING(g.end_ip_range)
答案 0 :(得分:2)
Try below (BigQuery Standard SQL)
#standardSQL
SELECT
p.* EXCEPT(ip_address_num),
g.country_code AS country_code
FROM (
SELECT *,
SAFE_CAST(SPLIT(p.ip_address, ".")[OFFSET(0)] AS NUMERIC)*16777216 +
SAFE_CAST(SPLIT(p.ip_address, ".")[OFFSET(1)] AS NUMERIC)*65536 +
SAFE_CAST(SPLIT(p.ip_address, ".")[OFFSET(2)] AS NUMERIC)*256 +
SAFE_CAST(SPLIT(p.ip_address, ".")[OFFSET(3)] AS NUMERIC) ip_address_num
FROM `dev.event_v1`
) p
INNER JOIN (
SELECT
SAFE_CAST(g.start_ip_num AS INT64) start_ip_num,
SAFE_CAST(g.end_ip_num AS INT64) end_ip_num,
country_code
FROM `dev.geo_ip_countries`
) g
ON ip_address_num BETWEEN g.start_ip_num AND g.end_ip_num