MySQL Query slow - поиск IP (забанен или нет) - PullRequest
16 голосов
/ 02 ноября 2011

В моем PHP-файле есть функция, которая проверяет, заблокирован IP или нет. По какой-то причине мой сайт работает очень медленно, и проблема заключается в том, что я проверяю, заблокирован ли IP-адрес или нет.

(я удаляю проверяющий код, и мой сайт снова работал быстро)

Вот мой код:

// index.php - everything redirects to this file in the .htaccess
<?php
include('config.php');
if(isIpBanned($_SERVER['REMOTE_ADDR'])) {
 die('access denied');
}
// rest of the code

вот моя функция

// config.php
<?php
function isIpBanned($db, $ip) { // $db is declared correctly
 $goodIP = $db->getRecord("SELECT is_banned FROM security.ip WHERE ip = '$ip'"); // this function works and return 1 or 0
 return (bool)$goodIP;
}

Выполнение этого запроса занимает от 2 до 3 секунд. Зачем? Я не оставил соединения или другие таблицы.

Спасибо

Ответы [ 2 ]

26 голосов
/ 02 ноября 2011
  1. Поместить (уникальный?) Индекс в столбец IP
  2. Используйте правильный тип данных, преобразовав текстовое представление в «родное» (ipv4 подходит для INT UNSIGNED, ipv6 для 2 BIGINT UNSIGNED): это уменьшит ваши таблицы и потребует меньше I / O во время сканирования

и, как примечание, даже если $_SERVER["REMOTE_ADDR"] должен быть безопасным, НИКОГДА НЕ ЗАБЫВАЙТЕ БРОСИТЬ ДАННЫЕ В SQL-ЗАПРОСАХ!

2 голосов
/ 02 ноября 2011

Поместите индекс в столбец ip.

В сети буквально тонны информации об анализе и улучшении запросов, поэтому я не буду повторять это для вас, но индекс определенно поможет.

Я думаю, security.ip - очень большая таблица, поэтому поиск становится медленным.

Недостаток индекса: запись становится несколько медленнее, поэтому, если вы много пишете в эту таблицу, вы можете попытаться перенести часть запрета в новую таблицу, скажем, banned_ips.

...