Mysql_connect (localhost/127.0.0.1) медленный на платформе Windows
Я использую Windows 7, Apache 2, PHP 5, MySQL 5, все они находятся на одной машине.
Я нашел интересную проблему, у меня есть следующий код:
$sql = "select * from user1";
$conn = mysql_connect("localhost", "root", "xxxxxxxx");
mysql_select_db("test1");
mysql_query("set names utf8");
$result = mysql_query($sql, $conn);
while ($row = mysql_fetch_assoc($result)){
foreach ($row as $key => $value){
echo $key." => ".$value." || ";
}
echo "<br/>";
}
mysql_free_result($result);
mysql_close($conn);
Время выполнения вышеуказанного кода составляет более 1 секунды.
Когда я использую 127.0.0.1
вместо localhost
, время работы около 10 мс.
Я попытался найти основную причину в Интернете, и это результат:
Недавно я перевел свою разработку с XP на Windows 7 и обнаружил, что веб-страницы, которые я разработал, занимали 5 секунд для загрузки. Конечно, это было неприемлемо, поэтому мне пришлось отследить проблему. В конце концов я выследил нарушающую функцию/метод pdo:: construct. Я также обнаружил, что mysql_connect занимает около 1 секунды, чтобы установить соединение. После небольшого поиска в Google я нашел объяснение, что php имеет проблемы с IPv6, и что вы можете исправить эту проблему, отключив IPv6 или переключившись на ipaddress 127.0.0.1 при подключении.
Интересно, в чем проблема IPv6 на PHP, просто хочу получить более глубокое недопонимание. Спасибо.
Ответы
Ответ 1
PHP пытается открыть соединение с localhost. Поскольку ваш компьютер подключен к вашей сети через IPv6, он сначала пытается запустить версию IPv6 "localhost", которая является IP-адресом:: 1
http://en.wikipedia.org/wiki/IPv6_address#Special_addresses
:: 1/128 - Адрес обратной связи является адресом одноадресной локальной адреса. Если приложение в хосте отправляет пакеты по этому адресу, стек IPv6 будет зацикливать эти пакеты обратно на один и тот же виртуальный интерфейс (соответствует 127.0.0.0/8 в IPv4).
Похоже, что ваш сервер MySQL не прослушивает этот адрес, вместо этого он привязан только к IPv4-адресу, поэтому, когда PHP не сможет открыть соединение, оно возвращается и пытается открыть localhost через IPv4 aka 127.0.0.1
Я лично предпочитаю использовать либо IP-адреса, либо использовать ether файл хостов Windows или эквивалент Mac, чтобы определить "поддельные" имена доменов, а затем использовать их при подключении к MySQL, которые разрешают IP-адреса. В любом случае, я точно знаю, будет ли использоваться IPv4 или IPv6-адрес.
Оба MySQL и Apache поддерживают IPv6, но вы должны сказать им явно использовать адрес IPv6. Для MySQL см.:
http://dev.mysql.com/doc/refman/5.5/en/ipv6-server-config.html
Для конфигурации Apache см.
http://httpd.apache.org/docs/2.2/bind.html
Apache поддерживает несколько IP-адресов, поэтому вы можете использовать их одновременно - если сетевая карта на компьютере имеет адрес IPv4 и IPv6. MySQL поддерживает только один адрес.
Ответ 2
PHP пытается подключиться к "localhost" в Windows 7/8/10, это:: 1, но MySQL не прослушивает сокеты IPv6, вы можете применить несколько исправлений:
1) В вашем файле хоста (C:/windows/system32/drivers/etc/host) установите localhost на 127.0.0.1
2) В PHP сервер MySQL изменяется с localhost на 127.0.0.1
3) В my.ini добавьте или отредактируйте: bind-address =::
Если адрес:, сервер принимает соединения TCP/IP на всех серверных IPv4 и IPv6-интерфейсов. Используйте этот адрес, чтобы IPv4 и IPv6 на всех интерфейсах сервера.
Рекомендуемый вариант, если у вас есть MySQL >= 5.5.3