V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
flash866
V2EX  ›  PHP

为什么 PHP 一直在优化程序执行效率,而不优化数据库连接?

  •  
  •   flash866 · 2015-01-09 15:03:30 +08:00 · 21131 次点击
    这是一个创建于 3605 天前的主题,其中的信息可能已经有所发展或是发生改变。

    底部的连接池技术,应该不是什么难事,比起优化PHP执行效率来说,应该very easy,但是至今仍然没有内置连接池技术(或者类似技术),还是一请求一线程,用完销毁,下次再重新连接。为什么不在PHP中内置相应的解决方案呢?

    29 条回复    2019-12-26 11:26:28 +08:00
    msg7086
        1
    msg7086  
       2015-01-09 15:12:42 +08:00
    mysql的连接池技术在1(shi)1(yi)年前就有了。
    tini8
        2
    tini8  
       2015-01-09 15:15:04 +08:00
    数据库持久连接老早就有了
    msg7086
        3
    msg7086  
       2015-01-09 15:18:47 +08:00   ❤️ 1
    至于像java之类那样「真正意义上的连接池」技术,在PHP上是根本不可行的。
    PHP就是被设计成每次运行完以后销毁一切状态,任何数据都不会带到下一个执行环境上去的。
    所以不可能内置一个全功能的「连接池」,而只能从第三方扩展里实现。
    如果你需要全功能连接池技术,那你就不能用PHP而需要用常驻内存型的语言,比如Java,ASPX,Ruby,Python,等等。
    sarices
        4
    sarices  
       2015-01-09 15:21:31 +08:00
    @tini8 长连接不是连接池
    楼主可以试试用swoole建立连接池
    cevincheung
        5
    cevincheung  
       2015-01-09 15:26:05 +08:00
    mysql: mysql-proxy、cobar、atlas
    postgresql: pgbouncer、plproxy、slony

    sql查询尽量不使用函数、外键(看场景)


    foreach ($rows50万 as $item) $db->select(sql);

    碰到这样的二逼程序员,数据库优化的再牛逼也没用。
    babyname
        6
    babyname  
       2015-01-09 15:38:43 +08:00
    我想问下这里的 webmaster 是傻逼吗?回复一个调侃php是世界上最好的语言帖子,不但删除帖子还封闭账号。
    flash866
        7
    flash866  
    OP
       2015-01-09 15:49:11 +08:00
    @sarices 为啥不能弄一个类似的内置进去?
    msg7086
        8
    msg7086  
       2015-01-09 15:50:21 +08:00
    @babyname 请勿劫持&Spam,谢谢。
    msg7086
        9
    msg7086  
       2015-01-09 15:51:28 +08:00   ❤️ 1
    @flash866 上面解释过了。PHP就是设计成这样的。
    如果内置一个进去,势必会破坏现有的设计结构,PHP也就不是PHP了。
    tomheng
        10
    tomheng  
       2015-01-09 16:04:23 +08:00   ❤️ 1
    个人觉得PHP亟待解决的问题有三个:效率、异步、并行。

    都解决好了才能成为真正的世界上最好的语言。
    kongkongyzt
        11
    kongkongyzt  
       2015-01-09 16:08:36 +08:00 via Android
    php从本身的设计上来说就不能支持这样的方式
    anewg
        12
    anewg  
       2015-01-09 16:44:45 +08:00
    @tomheng 放弃兼容性大刀阔斧的改有可能做到,但就phpng来看还是兼容之前版本代码,效率有很大提升,后面两个就算了吧
    Actrace
        13
    Actrace  
       2015-01-09 18:29:30 +08:00
    @tomheng
    请在php.net搜索搜索 cli pthread pcntl
    zts1993
        14
    zts1993  
       2015-01-09 19:39:38 +08:00
    因为实在是太简单,一个页面生命周期实在是太短了。。。。。所以得上memcache或者redis
    leonlu
        15
    leonlu  
       2015-01-10 08:54:13 +08:00
    php(不包括扩展)是使用进程做为最基础的调度单元的:

    1. 一个请求, 新建一个php进程.
    2. 一个进程里, 也只有一个线程.
    3. 一个请求处理完成自动释放进程.

    所以, 如果在一个请求里, 先搞一个数据库连接池, 请求结束再释放掉它, 成本太高了. php语言的设计者认为多线程是不安全的...异步编程是反人类的...所以他们把php设计成了这样的语言...
    mingzepeng
        16
    mingzepeng  
       2015-01-10 10:51:16 +08:00
    php作者设计php的初衷就是为了开发个人网站的,所以一开始并没有考虑那么多,而后期的不断升级也都是向下兼容的,而因为这种内嵌网页式的代码书写方式,还是被很多人吐槽为模板语言,至今很多人也并不承认php是一门独立的语言,不过这也并不影响它的流行。

    一般来说说,连接池技术,php在做网站开发的时候,因为其语言的执行机制,执行一遍然后销毁所有内存,所以确实是无法像java,ruby,python一样,从语言层面建立一个连接池,但可以通过第三方实现。

    而目前的大公司,访问量达到了一定的级别,通常的做法都是将各类服务封装为api,由php去调用,然后生成页面,而那些服务为了达到高性能,一般会才用java,c去开发,每个语言都有适合自己的地方。
    zzcworld
        17
    zzcworld  
       2015-01-10 13:35:13 +08:00 via iPhone
    请看react项目,可以让php变成node
    hitsmaxft
        18
    hitsmaxft  
       2015-01-10 23:29:16 +08:00
    mysqli 支持进程间链接重用的,看文档仔细点, 比如一个进程重用 200次,跟连接池也没啥区别, 因为fpm 本身就是池化管理的。 有时候并不是一定需要一种大伙都用的的方式才叫好。

    『还是一请求一线程,用完销毁,下次再重新连接』 不成立

    @leonlu php-fpm 能实现进程复用的, 并不是服务完毕就销毁的。


    实现得好好的你们都不知道的, 还在这抱怨别人用做, 太让人心寒了吧。。
    hitsmaxft
        19
    hitsmaxft  
       2015-01-10 23:29:47 +08:00
    更正 : 还在这抱怨别人用做 => 还在这抱怨别人不做
    leonlu
        20
    leonlu  
       2015-01-10 23:42:09 +08:00
    @hitsmaxft php-fpm怎么做到的进程复用? 求指导...
    hitsmaxft
        21
    hitsmaxft  
       2015-01-10 23:46:59 +08:00
    @leonlu fpm 的配置就那么几个, 你看下文档吧 , pm.max_requests
    leonlu
        22
    leonlu  
       2015-01-11 01:36:30 +08:00   ❤️ 1
    @hitsmaxft 确实如你所言, 是我对php的认识不足. 刚刚补了一下这里的知识, 应该是这样的:

    php有三种工作模式. 其中是最常见的是php作为一个模块工作在一个多进程的webserver中, 例如apache webserver. apache会启动一个主进程, 多个子进程(php). 主进程分发请求到子进程上处理. 目前流行的nginx + php-fpm应该也是类似这一种模式, ngnix会把请求转发给php-fpm处理. php-fpm是一个php进程管理器, 维护了一个php进程池, 在接收到请求后分发给php子进程.

    在这种模式下, php进程可以是一直存活的. 进程启动时会做进程相关的初始化操作, 比如加载插件. 对于接收到的请求, 会做请求处理的相关初始化->调用相应的php代码做业务操作->销毁请求上下文. 对于php程序员来讲, 每个请求的处理都是全新的上下文, 所有定义/对象/变量完全限定在单个请求处理的这个上下文中. 大家写的php代码到此结束. 当然, php进程也可以被销毁, 这与php-fpm的工作模式有关. 更多细节详见相关文档1+2.

    因此, 对于一个这样的php进程, 是可以做持久化数据库连接的, 只是稍有不同. 每个php进程只保留一个持久连接. 例如, php-fpm启动了20个php子进程, 对于同一个数据库和同一个用户名, 最多有20个持久连接. 对于同一个php进程所处理的多个请求, 它们都使用同一个数据库连接. 更多详见文档3.

    所以, 这个效果与使用一个连接池也差不多了. 持久连接数取决与php进程的数量. 最终, 持久连接数量/进程数量就需要按实际的情况来调优了.

    目前理解是这样, 如有误请指正.

    相关文档:

    1. php生命周期 http://www.slideshare.net/laruence/the-php-life-cycle
    2. php-fpm配置文档: http://php.net/manual/en/install.fpm.configuration.php
    3. php持久化连接: http://php.net/manual/en/features.persistent-connections.php
    hitsmaxft
        23
    hitsmaxft  
       2015-01-11 15:01:09 +08:00
    @leonlu

    对于 php 应用来说, 数据库的链接重用并不是瓶颈, 所以语言开发者不花这个心思也是正常的。
    从目前看来, php 应用的最大瓶颈, 是没有 jit 和 弱类型带来的性能负担。这也是 php 社区所应该尽快解决的问题。另外一个问题就是 yii2、lavarel 这些把开发者带进坑里的玩意,大型网站压根就没法用这些往死里浪费性能的重型框架。
    jiongjionger
        24
    jiongjionger  
       2015-01-11 15:23:19 +08:00
    1. 有持久链接
    2. 有扩展可以实现复用
    NCE
        25
    NCE  
       2015-01-11 22:21:19 +08:00
    1.php是自己封装的,近几年其他语言发展很快,所以优化php执行效率压力山大;
    2.php所使用的mysql是oracle自己发布的,要优化也是oracle的事情……

    你以为没有连接池技术么,虽然我没看oracle的代码,但我不信。
    yyinsomnia
        26
    yyinsomnia  
       2015-10-10 23:56:30 +08:00
    @hitsmaxft mysqli 支持进程间链接重用的
    文档应该不是这个意思。
    http://php.net/manual/en/mysqli.quickstart.connections.php

    Every PHP process is using its own mysqli connection pool. Depending on the web server deployment model, a PHP process may serve one or multiple requests. Therefore, a pooled connection may be used by one or more scripts subsequently.
    hpu423
        27
    hpu423  
       2016-02-29 11:27:31 +08:00
    mark 一下,我也很关注数据库连接池
    hheedat
        28
    hheedat  
       2016-12-08 15:25:05 +08:00
    @tomheng 说的好
    flash866
        29
    flash866  
    OP
       2019-12-26 11:26:28 +08:00
    好久没来了,已经改 JAVA 很多年了。。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2585 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 05:02 · PVG 13:02 · LAX 21:02 · JFK 00:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.