#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. Тем не менее, это было хорошее предложение.