由于最近公司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框架都没问题…
这到底是什么鬼?!