У меня есть две таблицы. Первая таблица (events
) выглядит следующим образом:
id int8
timestamp datetime
ip cidr
У меня есть вторая таблица (networks
), которая выглядит следующим образом:
id int8
network cidr
name text
В первой таблице ip
- это IP-адрес (например, IP-адрес входящего сетевого подключения в файле журнала). Во второй таблице network
представляет диапазоны IP-адресов (например, блоки IP-адресов для интернет-провайдера).
Я хочу объединить таблицы так, чтобы я мог получить networks.name
для каждой строки в events
. Мой SQL выглядит следующим образом:
select
e.ip
n.name
from
events e
inner join networks n on e.ip <<= n.network
limit 1000
Это, однако, очень медленно (> 1 с на возвращенную строку). У меня есть уникальный индекс BTREE, определенный на networks.network
, но это, кажется, не имеет значения. Обе таблицы содержат> 10 миллионов записей. Я (к сожалению) запускаю Postgres 9.6.12.
Есть ли эффективный способ вычислить это? Мне может показаться, что узким местом является операция «содержится внутри или равно» на JOIN
, но неясно, как заставить Postgres использовать индекс здесь. Возможно ли это?