【发布时间】:2013-11-06 05:45:43
【问题描述】:
我已在 BigQuery 中加载了我的应用程序日志,我需要根据这些日志中的 IP 地址计算国家/地区。
我在我的表和从MaxMind 下载的 GeoIP 映射表之间编写了一个连接查询。
理想的查询应该是带有范围过滤器的OUTER JOIN,但是BQ 在连接条件中仅支持=。
因此查询会执行INNER JOIN 并处理JOIN 每一侧的缺失值。
我已经修改了我的原始查询,以便它可以在 Wikipedia 公共数据集上运行。
有人可以帮我加快运行速度吗?
SELECT id, client_ip, client_ip_code, B.Country_Name as Country_Name
FROM
(SELECT id, contributor_ip as client_ip, INTEGER(PARSE_IP(contributor_ip)) AS client_ip_code, 1 AS One
FROM [publicdata:samples.wikipedia] Limit 1000) AS A1
JOIN
(SELECT From_IP_Code, To_IP_Code, Country_Name, 1 AS One
FROM
-- 3 IP sets: 1.valid ranges, 2.Gaps, 3. Gap at the end of the set
-- all Ranges of valid IPs:
(SELECT From_IP_Code, To_IP_Code, Country_Name FROM [QA_DATASET.GeoIP])
-- Missing rages lower from From_IP
,(SELECT
PriorRangeEndIP + 1 From_IP_Code,
From_IP_Code - 1 AS To_IP_Code,
'NA' AS Country_Name
FROM
-- use of LAG function to find prior valid range
(SELECT
From_IP_Code,
To_IP_Code, Country_Name,
LAG(To_IP_Code, 1, INTEGER(0))
OVER(ORDER BY From_IP_Code asc) PriorRangeEndIP
FROM [QA_DATASET.GeoIP]) A
-- If gap from prior valid range is > 1 than its a gap to fill
WHERE From_IP_Code > PriorRangeEndIP + 1)
-- Missing rages higher tan Max To_IP
,(SELECT MAX(To_IP_Code) + 1 as From_IP_Code, INTEGER(4311810304) as To_IP_Code, 'NA' AS Country_Name
FROM [QA_DATASET.GeoIP])
) AS B
ON A1.ONE = B.ONE -- fake join condition to overcome allowed use of only = in joins
-- Join condition where valid IP exists on left
WHERE
A1.client_ip_code >= B.From_IP_Code
AND A1.client_ip_code <= B.To_IP_Code
OR (A1.client_ip_code IS NULL
AND B.From_IP_Code = 1) -- where there is no valid IP on left contributor_ip
【问题讨论】:
-
看起来很酷!调查它..你能把 GeoIP 表放在一个新的数据集中并公开(尝试查询)。谢谢!
-
我一直在玩这个。感谢您公开该表。到目前为止,最困难的部分是处理空值。如果可以跳过空值,则可以更快地完成 - 从您编写的查询开始。
标签: performance google-bigquery geoip