为什么 PHP 一直在优化程序执行效率,而不优化数据库连接? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
flash866
V2EX    PHP

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

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

    底部的连接池技术,应该不是什么难事,比起优化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     Solana     3137 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 12:04 PVG 20:04 LAX 05:04 JFK 08:04
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86