thinkphp + mongodb项目中数据加载慢问题分析及解决
tp项目连接mongodb数据库读取数据慢问题解决。
项目环境:thinkphp框架 + mongodb数据库
项目测试demo
首先打开debug配置
// 数据库调试模式 'debug' => Env::get('database.debug', true),
日志查看
[ sql ] [ DB ] CONNECT:[ UseTime:0.000012s ] [ sql ] [ Mongo ] db.count({"count":"user","query":{"$and":[{"id":{"$ne":0}}]},"limit":0}) [ RunTime:5.113134s ] [ sql ] [ Mongo ] db.user.find({}).sort({"id":-1}).limit(10); [ RunTime:0.003165s ]
由此可见,查询在 count() 时导致时间太久,然后查看代码具体哪里使用
代码分析及解决思路
把日志里的查询代码放到命令里执行
db.user.count({id:{$ne:0}})
执行时间会比较长,把 count() 中的方法去掉,
再测试一次,会比较快,到此知道问题出在哪里了。
然后可以去代码中查看
// 这里正是日志里记录的长时间查询条件,注释掉此条代码 // $this->model->where("id","<>",0); $list = $this->model ->order($sort, $order) ->paginate($limit); foreach($list as $k=>$v){ $v["_id"] = $v["_id"]->__toString() ; } $result = array("total" => $list->total(), "rows" => $list->items());
注释代码后,查询数据报错
BSON field 'count.query' is the wrong type 'array', expected type 'object'
报错原因:
在 think-mongo 版本,
vendor/topthink/think-mongo/src/Builder.php
文件中,parseWhere 方法在做过滤条件初始化的时候,没有考虑周全,将数据类型定义为了数组。
解决办法:
在 parseWhere 方法返回的时候做一个判断,如果 $filter 为空,就重新定义为 stdClass 对象。
修改的方法就是在 return 前添加如下代码:
// 修改代码 开始 if (empty($filter)){ // 返回空对象 return new \stdClass(); }
查询一下加载读取速度正常了,看看日志记录
[ sql ] [ DB ] CONNECT:[ UseTime:0.000012s ] [ sql ] [ Mongo ] db.count({"count":"user","query":{},"limit":0}); [ RunTime:0.003134s ] [ sql ] [ Mongo ] db.user.find({}).sort({"id":-1}).limit(10); [ RunTime:0.003165s ]
相关文章