【问题标题】:mysql_connect (localhost / 127.0.0.1) slow on Windows platformmysql_connect (localhost / 127.0.0.1) 在 Windows 平台上慢
【发布时间】:2012-07-24 17:14:54
【问题描述】:

我使用的是 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 秒来建立连接。经过一番谷歌搜索后,我发现了一个解释,说明 php 存在 IPv6 问题,您可以通过禁用 IPv6 或在建立连接时切换到 ipaddress 127.0.0.1 来解决问题。

我想知道 PHP 上 IPv6 的问题是什么,只是想更深入地了解。谢谢。

【问题讨论】:

  • 您的 mysql 服务器是否在 ::1 上运行?如果不是,php 可能会尝试通过 ipv6 连接,如果失败,它将回退到 ipv4。这应该需要更长的时间。
  • 抱歉,我不明白“您的 mysql 服务器是否在 ::1 上运行?”方法?是不是意味着在同一台机器上运行多个mysql服务器?
  • 感谢您提出这个问题。我刚刚通过使用 127.0.0.1 而不是 localhost 大大加快了我的网站速度。

标签: php mysql performance localhost mysql-connect


【解决方案1】:

PHP 正在尝试打开到 localhost 的连接。因为您的计算机通过 IPv6 连接到您的网络,所以它首先尝试 IPv6 版本的 'localhost',它的 IP 地址为 ::1

http://en.wikipedia.org/wiki/IPv6_address#Special_addresses

::1/128 — 环回地址是单播 localhost 地址。如果 主机中的应用程序将数据包发送到此地址,即 IPv6 堆栈 将在同一个虚拟接口上循环这些数据包 (对应 IPv4 中的 127.0.0.0/8)。

您的 MySQL 服务器似乎没有监听该地址,而是仅绑定到 IPv4 地址,因此一旦 PHP 无法打开连接,它就会回退并尝试通过 IPv4 aka 127.0.0.1 打开 localhost

我个人更喜欢使用 IP 地址或使用 Windows 主机文件或 Mac 等效项来定义“假”域名,然后在连接到解析为 IP 地址的 MySQL 时使用这些名称。无论哪种方式,我都可以确切地知道是使用 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 只支持一个地址。

【讨论】:

  • 我已经做了一些步骤来调查这个问题。我先去C:/Windows/System32/drivers/etc/查看windows主机文件,发现里面的所有信息都被注释掉了。所以我取消注释“127.0.0.1 localhost”并执行mysql连接。执行时间约为 10 ms。然后我回到主机文件,注释“127.0.0.1 localhost”并取消注释“::1 localhost”。之后,我再次运行程序。结果,程序无法连接到mysql服务器。
  • mysql服务器版本为5.1.03。因此,我断定问题可能是由于Mysql server 缺少对ipv6 的支持。因此解决方案可能是避免使用 ipv6 或启用 MySQL 服务器 ipv6 支持。欢迎任何建议和补充。
  • 我通过cmd使用“netstat -an”,发现有两行:“TCP 0.0.0.0:80 0.0.0.0:0 LISTENING”和“TCP 0.0.0.0:3306 0.0.0.0 :0 听”。但是没有 [::]:80 或 [::]:3306。这是否意味着apache和mysql都不支持ipv6?
  • 他们支持它们 - 添加了指向主要答案的链接。
【解决方案2】:

PHP 正在尝试连接到 Windows 7/8/10 中的“localhost”,它是 ::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 的建议选项

【讨论】:

  • 绑定地址 = :: 帮了我!
  • @marcovtwout 哪个 MySQL 版本?你得到了什么错误?
  • @Jose Nobile 如果我理解正确,解析到 localhost 不再从主机文件完成。见stackoverflow.com/a/15436435/729324
  • @marcovtwout 来自我的测试,localhost 跟随主机文件。无论如何,推荐的选项是#3
猜你喜欢
  • 2011-04-12
  • 2011-04-30
  • 1970-01-01
  • 2014-10-28
  • 2021-11-03
  • 1970-01-01
  • 2011-02-04
  • 2023-03-18
相关资源
最近更新 更多