Снежинка, как правило, не очень хорошо работает при сканировании дальности, например, у вас есть
ON
A.UNIQUE_IP_NUMBER >= B.IP_START AND
A.UNIQUE_IP_NUMBER <= B.IP_END
, который, как мы обнаружили, between
помогает в некоторых случаях, и ваш матч - хороший пример того, где у вас может быть лучшая производительность. Какой шаблон используется в PARSE_IP help
ON A.UNIQUE_IP_NUMBER BETWEEN B.IP_START AND B.IP_END
, мы даже обнаружили, что >= & <
быстрее использует BETWEEN
и <
в конечной строке:
ON A.UNIQUE_IP_NUMBER BETWEEN B.IP_START AND B.IP_END
AND B.IP_START < B.IP_END
но там, где мы обнаружили, что SNOWFLAKE сияет на равных соединениях, мы обнаружили, что увеличение данных в 32 раза, как показано ниже, дает огромное увеличение скорости, даже более 1 миллиарда строк, соединяющихся до 100 миллионов.
WITH ip_geo_city AS (
SELECT
PARSE_IP(a.network, 'INET') as ipv4_range_end
AS_INTEGER(ip:ipv4_range_end) AS ip_end,
AS_INTEGER(ip:netmask_prefix_length) AS ip_netlenmask
BITOR(BITSHIFTLEFT(ip_netlenmask, 32), ip_end) as lookup_key
b.country_name AS country_name
FROM geolite_city_block_ipv4 AS a
LEFT JOIN geolite_locations AS b
ON a.geoname_id = b.geoname_id
ORDER BY lookup_key
), ipv4_masks AS (
SELECT ROW_NUMBER() OVER(ORDER BY TRUE) as rn
,32-rn as net_len
--,BITSHIFTLEFT(1, rn) as b
--,b-1 as bm
--,BITNOT(bm, 4294967295) as bn
--,-b as bnn -- due to two's complement -b = BITNOT(b-1)
,BITAND(4294967295, -BITSHIFTLEFT(1, rn)) as net_mask
FROM table(generator(rowcount => 31)) ;
), unique_ip_number_lookups AS (
SELECT a.unique_ip_number
,BITOR(BITSHIFTLEFT(m.net_len, 32), BITAND(m.net_mask, a.unique_ip_number) as lookup_key
FROM unique_ip_number AS a
JOIN ipv4_masks as m
)
SELECT
a.unique_ip_number,
b.country_name
FROM
unique_ip_number_lookups AS a
LEFT JOIN ip_geo_city AS b
ON a.lookup_key = b.lookup_key