【问题标题】:mysql connections bottle neck via PHPmysql 通过 PHP 连接瓶颈
【发布时间】:2009-07-03 13:22:08
【问题描述】:

目前我们正在 $_SESSION 中恢复 MySQL 连接,以节省建立与 MySQL 的连接的往返时间,

但问题是连接数很快就超过了限制,

那么你们的解决方案是什么?

你是每次都新建一个连接,用完就关闭,还是像我一样恢复?

【问题讨论】:

  • 曾经计划回答问题/投票选出人们提供的正确答案?
  • 问题已得到解答 - 使用 mysql_pconnect 而不是 $_SESSION ...
  • 所以您是说在您提出的 208 个问题中,只有 2 人曾经幸运 足以被你点赞?大约 10 lucky 足以被视为正确答案?我发现非常很难相信你得到了 198 个错误答案,我想知道如果是这样的话你为什么会回来。你在滥用这里的用户对你的恩惠,我觉得这非常冒犯。
  • @thief,未验证,需要合理的证明。
  • @Ian Elliott,我会接受你的建议,谢谢

标签: php mysql connection


【解决方案1】:

除了 DGM 的评论之外,resource 类型(如 MySQL 连接引用)不会通过会话恢复。 $_SESSION 的内容使用serialize() 进行序列化,并与会话 ID 一起存储,以在会话再次启动时恢复。

serialize 的文档指出:

string serialize( mixed $value )

value -- 要序列化的值。 serialize() 处理所有类型,resource 类型除外。

这意味着您实际上正在重新连接每个请求。按照 noselasd 的建议使用mysql_pconnect() 可能会缓解这种情况。请务必注意its manual page 上的注释,尤其是这需要 PHP 作为模块运行。

【讨论】:

  • 我没有看到您如何得出“您实际上正在重新连接每个请求”的结论,为什么序列化会导致重新连接,您能否提供更多详细信息?
  • 序列化创建对象的文本表示...因为 PHP 是一种脚本语言(除了缓存之外没有真正的持久性,这实际上只是转储和重新加载变量)没有办法持久化跨请求的资源。脚本执行完毕后,一切都关闭了。
  • 这里的关键是mysql如何检测连接是否关闭。如果它每次都为一个新的PHP连接分配一个唯一的ID,那么在PHP中序列化它不会关闭那个连接,对吧?
  • mysql_pconnect() 如果无法从它保留的池中选择一个,则创建一个持久连接。这个可用连接池在 webserver 中的 PHP 模块的生命周期内持续存在,所以如果 webserver 重新启动(或者 PHP 不是作为模块运行,而是作为 CGI 运行),那么池将被清空,这与使用mysql_connect()。我相信PHP持有的连接会超时,但我不知道具体情况。
  • mysql_connect() 建立的任何连接都将创建 resource 对象,这些对象在脚本结束时释放,无论它们是否被放入会话中。 resource 是对由一些非 PHP 代码(例如数据库连接)创建的内部对象的引用,它只有一个索引和一个模糊的“类型”。 PHP 不知道比这更多的细节——它可以容纳任何东西。这就是为什么它不能被序列化和反序列化。如果/当 resource 被序列化时,信息会丢失,因为细节只对资源处理程序(例如 MySQL 函数库)很重要
【解决方案2】:

在会话中存储连接是行不通的。不要那样做。如果它实际上在后续访问中重用该连接,我会感到惊讶,因为它涉及网络访问,并且您不能将网络连接存储在文件中!充其量,它会在下一页查看时重新连接,这不会为您带来任何好处。在最坏的情况下,对于每个保持打开但未正确关闭的请求,您都有一个单独的连接。

编辑 - 更多想法

此外,以优化的名义,为什么还要费心呢?您是否真正分析过您的代码并发现这是真正的瓶颈?只需以最简单明了的方式编写代码,然后在发现已测量的实际问题时担心优化。除非您有一个 非常 大的站点,否则数据库连接不是任何瓶颈的根源。

【讨论】:

    【解决方案3】:

    我在每个新页面调用上都设置了一个新连接。我确实在整个页面中使用 1 连接,并在页面发送到浏览器时关闭它。

    我怀疑你优化得太早了,给自己带来了不必要的痛苦。

    【讨论】:

    • 因为每3秒就有一个ajax请求到服务器,所以我觉得有必要这样做。
    • 你试过没有存储吗?这是否真的会导致问题,或者您是否解决了您预期的问题?
    • 是后一种情况,但我认为这是合理的。
    • 您可能正在解决一个您没有遇到的问题。我认为在解决问题之前找出问题是合理的。
    • 我现在有一个问题:为什么使用 mysql_pconnect 保持连接,而使用 mysql_connect 则不然?而mysql_close是否只有mysql_pconnect才需要?既然mysql_connect的情况下,连接会自行关闭?
    【解决方案4】:

    PHP 确实缺乏连接池,这是其他语言/框架中非常常见的概念。

    使用 mysql_pconnect 可以让你走得更远。不过,在会话中存储连接听起来是一件非常糟糕的事情,您会消耗太多资源。

    【讨论】:

    • 我遇到的麻烦是在数据库级别,而不是PHP,我认为使用mysql_pconnect类似于将其恢复到$_SESSION,对吧?
    • 在 $_SESSION 中使用它会将连接限制为仅该会话。这可能是一个巨大的浪费。使用 mysql_pconnect 允许任何人不管会话如何使用它。如果您在尽可能短的时间内使用连接,那将是一个巨大的胜利。
    • 使用mysql_pconnect会不会造成并发问题?
    • @noselasd:在会话中存储数据库连接资源不起作用,因此推测它是否加快了速度是没有意义的。
    • @shore: 不,通常 pconnect 是可以的,但只有在某些情况下才会有性能提升。
    【解决方案5】:

    数据库连接对象是一种资源,这意味着它是 php 世界之外的神奇事物(afaik 是一个 c 结构或对象)。你不能序列化一个资源,在会话中存储一个变量意味着序列化它(同样的事情serialize(); 做)。

    php 具有“无共享”的性质,这意味着它不与其他请求共享资源。 2个请求可能都来自用户A,或者一个用户A和一个用户B,无法知道。每个请求都被封装,在两个请求之间建立逻辑连接的唯一非常有限的“解决方法”是会话。其他一切都必须从外部抓取(数据库、文件、memcached),所以这不再是 php 的问题了。

    因此,在请求之间共享数据库资源从来都不是本意。对于每个请求他自己的mysql_connect。我认为这是使 mysql 首先在 php 社区中流行的主要原因。 mysql 的连接速度比其他 rdbms 快很多,因为它的功能更少(没有事务、没有视图、没有触发器、什么都没有),所以它非常适合。

    mysql_pconnect did 连接池(但在不同级别),但它也不是魔杖。现在你无论如何都应该使用 PDO(而且 PDO 不支持它 afaik)。

    如果您的应用程序变慢,问题就出在其他地方。

    我的建议:

    • 无论你认为你做什么......你没有共享连接,所以看看那个。事实上,您的应用程序可能会因为您的技巧而变慢(如果它为每个查询创建连接)。删除该功能并再次测试。
    • 检查您的查询 (EXPLAIN SELECT * FROM foo;)
    • 正确设置索引
    • 使用缓存(例如 memcached)

    我看到的最常见的性能问题是人们认为他们应该寻找一个最常见的性能问题,而不是通过测量来找出他们实际的性能问题到底是什么。
    - cary millsap

    【讨论】:

    • 你谈论它是这样的,但很少谈论它是如何实现这个目标的,似乎。
    • 如果您想知道它是如何实现该目标的,请将其作为一个新问题提出 - 或研究源代码。
    【解决方案6】:

    如其他答案所述,php 无法以文本形式存储资源,只是无法完成。

    如果您使用的是 php 5.3 和 mysqli,您现在可以通过在使用“p://”连接时为主机参数添加前缀来使用持久连接。

    使用 mysql 扩展,使用 mysql_pconnect。

    你可以设置一个mysql代理http://forge.mysql.com/wiki/MySQL_Proxy

    【讨论】:

    • 我只想问一个问题:使用mysql代理后会有多少连接?
    • 这真的取决于为什么连接首先堆积起来...... mysql代理将重用池中的连接(如果我没记错的话)。这是 IMO 的真正问题。
    • 有没有关于mysql代理应该如何重用连接的详细参考? BTW,如果我们只使用mysql_pconnect,为什么执行完成后连接仍然存在?PHP不是应该在完成后释放所有资源吗?mysql_pconnect如何实现永久连接?
    • forge.mysql.com/wiki/MySQL_Proxy_FAQ,大约一半的地方提到了连接池功能。
    • 关于 mysql 代理的 PDF 演示文稿,其中的几张幻灯片提到了连接池 downloads.mysql.com/forge/slides/MySQL-Proxy.pdf
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    • 2013-12-16
    • 1970-01-01
    • 1970-01-01
    • 2018-12-30
    相关资源
    最近更新 更多