Эффективный поиск диапазонов IP на PHP и MySQL

#php #mysql

#php #mysql

Вопрос:

У меня есть база данных с примерно 100 000 записей диапазонов IP-адресов, от которых мой веб-сайт будет отклонять запросы.

Таблица, хранящая эти диапазоны, имеет формат

 ip_from (int)
ip_to (int)
 

Используя PHP, я преобразую IP-адреса пользователей в целочисленное значение, используя ip2long

Затем я использую следующий SQL-запрос, чтобы определить, присутствует ли IP-адрес пользователя в диапазоне в таблице.

 SELECT `ip_from` 
FROM `ip2location_proxy`
WHERE '".$ip."' BETWEEN ip_from AND ip_to LIMIT 1
 

Проблема в том, что это создает большую нагрузку на сервер. Мне интересно, может ли кто-нибудь предложить лучший метод определения того, находится ли IP-адрес в пределах диапазона, указанного в базе данных, например, в качестве альтернативы использованию BETWEEN команды.

Комментарии:

1. Елки-палки, почему у вас есть 100 тысяч IP-адресов, которые вы запрещаете?? Я не уверен, действительно ли существует способ эффективного поиска по 100 тысячам записей в каждом отдельном HTTP-запросе.

2. Убедитесь, что у вас есть индекс либо ip_from или ip_to (я не думаю, что индексация их обоих сделает это лучше).

3. Если вы используете ip2location, как указано в вашем запросе, почему бы вам не использовать их формат BIN, который намного эффективнее и быстрее?

4. @HankyPanky ip2location.com/databases/px2-ip-country используется ли база данных. Я не верю, что у них есть формат BIN для этого.

5. @Barmar К сожалению, индекс уже есть, я начинаю думать, что не смогу добиться большей эффективности.

Ответ №1:

У нас были похожие проблемы с BETWEEN. Попробуйте использовать два отдельных запроса с ОБЪЕДИНЕНИЕМ. Честно говоря, я действительно не знаю, почему это было быстро, в то время как BETWEEN был медленным.

 SELECT `ip_from` 
FROM `ip2location_proxy`
WHERE '".$ip."' >= ip_from

UNION ALL

SELECT `ip_from` 
FROM `ip2location_proxy`
WHERE '".$ip."' <= ip_to
 

Ответ №2:

Предполагая, что ваши индексы хороши, и вы работаете в системе с не очень низким энергопотреблением или медленным доступом к диску, я предлагаю следующее:

Если вы обнаружите, что у вас большой диапазон белого списка, например, 0 - 2147483648 тогда вы можете попробовать сначала убедиться, что IP-адрес не входит в диапазон белого списка, а затем проконсультироваться с вашей базой данных.

 <?php
if($ip > 2147483648)
{
    // consult the ip2location_proxy table
}
 

Кроме того, рассматривая пример данных на https://www.ip2location.com/databases/px2-ip-country , может быть, вы можете попробовать удалить ненужные столбцы, которые не ip_from являются и ip_to

Комментарии:

1. К сожалению, индекс начинается в основном с 0. Тем не менее, это было хорошее предложение.