场景描述从全文搜索或缓存中获取ID,根据ID查询数据库获取基本信息,进行页面展示SQL:select*fromtablewhereidin(id1,id2,id3...id40)该场景常规方案是在redis中缓存一份id对应的基本信息,mysql只作为后端存储。我们做如下测试,试试mysql能否应对这种查询场景。然而根本原因是DBA告诉我,MySQL的性能已经非常强大了。数据量说明1.8亿条数据使用Oneproxy分成200张数据表(200张表在同一台机器上)。因为id是随机的,所以oneproxy在查询的时候会分散查询到所有后端MySql的性能指标。每次查询的并发查询数ResponsetimeMySqlserver腾讯云提供的MySQL服务mysql的具体配置这里就不一一列举了,即以下性能报告只是在特定场景下的性能分析,不代表mysql的“真实”性能。本文的核心是提供一种测试方法,而不是简单的提供数据报告。测试程序介绍基础知识:php和swoole协程使用协程来控制程序的并发数,在每个协程中执行一个查询。查询完成后,将通知管道开始新的查询。程序代码mysql_test.php'127.0.0.1','port'=>3307,'user'=>'root','password'=>'123456','database'=>'','超时'=>10];Swoole\Coroutine::create(function()use($mysqlconf){$stime=microtime(true);//程序启动时间$pool=newMysqlPool($mysqlconf);$chan=newchan(MAX_MYSQLPOOL_NUM);//并发数,使用协程间通道通信for($i=1;$ipush('x');Swoole\Coroutine::create(function()use($pool,$chan,$i){//测试的业务逻辑开始$conn=$pool->get();if($conn){$sql="select/*parallel*/*fromtablewhereid在(".implode(',',getRandpid()).')';$time1=microtime(true);$conn->query($sql);$time2=微时间(真);if($i%intval(TESTCOUNT/10)==0){//输出执行的进度echo"\nfinish$i/".TESTCOUNT;}$pool->put($conn,(($time2-$time1)*1000));//不为每个查询耗时单独创建实例,直接修改连接池类进行简单统计}else{echo"\nconnectmysqlfail,skipSQL";}//业务逻辑结束$chan->pop();});}$etime=微时间(真);echo"\n=============执行结果=============";echo"\n并发数:".MAX_MYSQLPOOL_NUM;echo"\n查询次数:".TESTCOUNT;echo"\n总执行时间:".intval($etime-$stime)."Second\n";echo"\nQPS(查询次数/总耗时):"。intval((TESTCOUNT/($etime-$stime)));echo"\n每次查询花费的平均时间Value:".intval($pool->alltime/TESTCOUNT)."ms";echo"\n============结束==============\n";die;});//数据库连接池,https://wiki.swoole.com/wiki/page/852.htmlclassMysqlPool{protected$pool;私人$mysqlconf;公共$所有时间;公共职能__construct($mysqlconf){$this->pool=newSplQueue();$this->mysqlconf=$mysqlconf;$this->alltime=0;}公共函数put($mysql,$time=0){$this->pool->push($mysql);$this->alltime+=$time;}publicfunctionget(){//空闲连接if(count($this->pool)>0){return$this->pool->pop();}$mysql=newSwoole\Coroutine\Mysql();$res=$mysql->connect($this->mysqlconf);if($res==false){echo"\nconnecterrorinfo:".$mysql->error."\n";返回错误;}else{返回$mysql;}}}//随机生成的数字函数getRandpid(){for($i=0;$i<40;++$i){$ret[]=rand(1,185724600);}return$ret;}测试1:直接连接mysql,查询单表的性能测试代码:修改以上代码1:修改mysql配置为直接连接mysql,而不是oneproxy即端口由3307改为33062:“业务逻辑”部分的SQL改为:$sql="select*fromtable_10whereidin(".implode(',',getRandpid())。')';测试命令:phpmysql_test.php11000//并发为1,查询1000次phpmysql_test.php101000//并发为10,查询1000次phpmysql_test.php5010000//并发为50,查询10000次...phpmysql_test.php500100000//并发500,查询10万次测试结果:数据库单表分析测试结果:根据主键查询单表,mysql的性能基本可以满足正常业务的需求.测试2解释查询oneproxy。因为查询id是随机的,每次检查oneproxy,对应查询40张mysql表。即当oneproxy的并发数为1时,对应的mysql并发数为40。测试代码:以上提供的代码为本案例代码,无需修改。测试命令:phpmysql_test.php11000//并发为1,查询1000次phpmysql_test.php101000//并发为10,查询1000次phpmysql_test.php5010000//并发为50,查询10000次...phpmysql_test.php10010000//并发为100,查询10000次测试结果:oneproxy并行查询结果分析:1:oneProxy是mysql的代理,对查询性能基本为0消耗。当oneproxy的查询并发为5时,mysql对应的查询并发为200。测试2的结果,并发为5,每次查询耗时30ms。测试1,mysql并发200,每次查询耗时29ms。可以得出结论,oneproxy对性能的消耗为零。2:每次查询耗时过高,该方案只能用于流量非常小的业务。测试三:后端mysql表分布到多台机器,一分为二。测试结果:分析:mysql分在两台机器上。在并发数相同的情况下,每次查询花费的时间可以翻倍。推测:mysql表分机较多,每次查询耗时可以达到测试1的结果,可以满足正常业务需求。最后,在关注性能的同时,还要关注系统稳定性、开发者易用性、易维护性。更多学习内容,可访问【与各大厂商对比】优质PHP架构师教程目录。只要能读懂,就能保证你的薪水更上一层楼(持续更新中)。以上内容希望对大家有所帮助。很多PHPer总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道从哪里开始改进,我整理了一些这方面的资料,包括但不限于:分布式架构,高可扩展性、高性能、高并发、服务器性能调优、TP6、laravel、YII2、Redis、Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等知识点免费分享给你如果你需要高级干货。有需要的可以点击链接领取高级PHP月薪30k>>>架构师成长之路【免费获取视频和面试资料】