kashey
@kashey
Программирую большую половину жизни

Как быстро проверить попадание IP в диапазон?

На основе stackoverflow.com/questions/22125474/mysql-optimal... и миллионов других вариантов.
В общем случае
select * from ipBase where ? between start_ip and end_ip
работает не совсем правильно - запрос преобразуется в
select * from ipBase where start_ip<? and end_ip>?
Это формирует так называемый "открытый" интервал - найти все значения start_ip которые меньше заданного, и все end, которые больше.
Так как мы проверяем "точку" - это приведет в выборке вообще всех значений в базе в первой части, и пересечению с результатами второй.
Долго, дорого, очень.
Обычно решением является ограничить область поиска, те создать закрытый интервал. По факту диапазоны редко когда бывают более 32к значений "длиной", и запрос можно преобразовать в
select * from ipBase where ? between start_ip and end_ip and start_ip between ?-32k and ?.....

Это сильно быстрее, но не "алгоритмично",

Интересуют именно красивые идеи для решения задачи на SQL, и вообще (академические) варианты решения нахождения вхождения точки в отрезок. За O(logn) или меньше :P
  • Вопрос задан
  • 674 просмотра
Пригласить эксперта
Ответы на вопрос 2
Fadmin
@Fadmin
Сколько записей у вас в таблице?
Как хранится IP адрес, какой тип данных?
Если IPv4 то подозреваю что записей немного.
Общим решением будет навесить индекс на оба поля, и приджойнить таблицу к себе же.
Ответ написан
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
select id, 
GREATEST(INET_ATON(ipBase.ip)-INET_ATON(start_ip)) as ip2
LEAST(INET_ATON(end_ip)-INET_ATON(ipBase.ip)) as ip3
from ipBase
where ip2<start_ip OR ip3>end_ip
group by id

что-то в этом духе, но не проверял...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы