ThinkPHP连接mongo的奇异现象

在将部分业务从MySQL迁移到MongoDB后,测试发现MongoDB在大规模使用时查询速度大幅下降,尤其是在实例化多个Model时。通过调试发现,即使只保留一个Model实例化,连接速度仍慢至1秒。进一步研究ThinkPHP的MongoModel和_modelAfterDb()回调方法,发现MongoClient的实例化过程可能是问题所在。然而,创建单独的MongoDB demo测试速度正常,排除了框架和本地配置的问题,暗示可能是个别项目或特定环境下的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于最近公司P(po)V(fu)上(wu)升(qi),我们想出了不复杂的查询逻辑,由Mongo数据库代替mysql数据库的解决方案

于是经过一番改造,终于把一坨逻辑改成了mongo,接着进行了多次测试,以下是测试中的一部分信息,出于安全考虑,字段和表名已经隐藏,请党和人民放心。

mysql程序运行信息:
这里写图片描述

mongo程序运行信息:
这里写图片描述

结论:多次测试表示,mongo的整体速度都优于mysql(非复杂查询)

那么这样一来,mongo的方案就确定下来了。

于是,我们进行了更大规模的改造,将一个功能模块都改成了mongo,结果,问题发生了。

不知道为什么,mongo的查询速度大幅度下降,由于我们原来的逻辑属于集中式的A(luo)P(ji)I(hun)方(luan)式,改造工作遇到了一些瓶颈,所以不得不在公有层就进行大规模Model实例化,所以问题开始,锁定在了这里

这里写图片描述

可以看到,我在这里做了一个断(jie)点(shu)调(cheng)试(xu),然后对比程序的执行时间,同时mysql的也是一样的逻辑

当然,由于初始化的速度非常快,这里使用的时间单位是毫秒/100

mongo速度:
这里写图片描述

这是多少?——1秒!震惊了,足足1秒钟,仅仅是实例化6个model并构建mongo连接

好吧,也许是think的mongo模型没有做判断,导致我连接了6次mongo数据库?

这里写图片描述

果断只留下一个实例化,结果——还是1秒多….

我的连接方式如下:
BaseModel,所有自定义Model的父类,继承think的MongoModel:
这里写图片描述

自定义Model,传递表名,调用父类构造:
这里写图片描述

没看出任何问题的我也是醉了,于是不得不思考think的机制问题,于是一路追上去…

路过think的MongoModel,没发现调用,于是找到Model类的构造的db方法
这里写图片描述

没有发现什么异常,在这里断点依然很慢

继续追查,发现了直到发现了_after_db()
这里写图片描述

这个回调方法是空的,而model没有父类,很显然,他调用的是子类的回调方法,那么根据我们的逻辑,子类必然是MongoModel,好吧,我们继续走…

这里写图片描述

找到了切换数据库的方法…原来think是这么个运作流程…
db成员变量就是当前数据库的连接,做过自己框架的同学想必和我一样,对这个成员变量很是熟悉吧…

好,我们来dump一下,看看它到底是谁…

这里写图片描述

DbMongo…在驱动目录下找到DbMongo下的对应切换数据库方法
这里写图片描述

很显然,第一次进入的时候,我们会直接获取数据库连接(这里的逻辑很很明显的告诉我们,重复连接神马的,think没这么2)

这里写图片描述

这里写图片描述

重头戏来了….我们找到了最根的数据库连接,明显看到了MongoClient扩展的实例化,于是我直接在这里打断了程序…结果发现依然很慢….
这里写图片描述
再试,索性连参数都不传,直接连…好吧,也很慢….

也就是说,与之前的逻辑无关,本身MongoClient就很慢!

OMG!难道是我本机配置不对?赶紧写个demo压压惊…

这里写图片描述

好,来看看速度…

这里写图片描述

….这是啥,火箭么?!

顺便来一个PDO直连mysql的demo,测试速度如下:

这里写图片描述

明显,本地配置没问题,代码没问题,甚至think框架都没问题…

这到底是什么鬼?!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值