mongoDB 性能优化:如何使用普通查询语句替代 aggregate 操作?
来源:互联网 发布:ubuntu 16 rc.local 编辑:程序博客网 时间:2024/04/28 07:11
我们知道,mongo 里的普通查询语句是没有分组查询功能的,如果要实现类似于关系型数据库 SQL 里的 group by 操作就要用 aggregate。遗憾的是副本集中,aggregate 操作是在主库执行(比如笔者的 3.0.3 就是这样的,据说 mongo 新版本会改善这一状况 - 将 aggregate 操作放到从库执行),这对于读写分离的副本集是不合理的,大并发时的大量慢查询操作很容易将主库给拖死。
要想提高主库性能,优化 aggregate 慢查询是一个不错的办法,但是如果能将 aggregate 换成普通查询语句进而去从库执行(实现读写分离)也不失为一个不错的优化方案。本文将以一个实战例子详解如何使用普通查询语句替代 aggregate 操作,本文示例代码均采用 go 语言实现。
代码解析:find 对象是一个用于存放查询条件的 BSON map(类似于 SQL 里的 where 从句),total 是一个自定义的用于存放返回结果的结构体(类似于 JDK JDBC API 里的 ResultSet)。上述查询使用了两层 group,第一层按 merId 进行分组,第二层对第一层分组后的 merId 个数进行统计。
理解其要做的事情之后,我们可以还是按 find 的条件进行查询,调用查询结果(是一个 v2.Query 对象)的 Distinct 函数对 merId 进行分组 - 这一步实现了上述语句的第一层 group;merId 分组后我们在对这个分组执行查看长度的操作,实现上述 aggregate 中的第二层分组。go 语言示例代码如下:
这段代码实现的功能和上述 aggregate 实现的功能是一样的,但它是在从库执行。美中不足的是要把所有符合条件的 merId 都从数据库拉到应用,之后由应用计算其长度,因为 Distinct 返回的结果是一个 error 接口,不能够计算 merId 集合的长度,但牺牲的这点应用内存和应用数据库带宽能换来 mongo 副本集主从库的读写分离,还是值得的。
要想提高主库性能,优化 aggregate 慢查询是一个不错的办法,但是如果能将 aggregate 换成普通查询语句进而去从库执行(实现读写分离)也不失为一个不错的优化方案。本文将以一个实战例子详解如何使用普通查询语句替代 aggregate 操作,本文示例代码均采用 go 语言实现。
database.C(col.name).Pipe([]bson.M{{"$match": find},{"$group": bson.M{"_id": "$merId"}},{"$group": bson.M{"_id": "null", "total": bson.M{"$sum": 1}}},}).One(&total)
代码解析:find 对象是一个用于存放查询条件的 BSON map(类似于 SQL 里的 where 从句),total 是一个自定义的用于存放返回结果的结构体(类似于 JDK JDBC API 里的 ResultSet)。上述查询使用了两层 group,第一层按 merId 进行分组,第二层对第一层分组后的 merId 个数进行统计。
理解其要做的事情之后,我们可以还是按 find 的条件进行查询,调用查询结果(是一个 v2.Query 对象)的 Distinct 函数对 merId 进行分组 - 这一步实现了上述语句的第一层 group;merId 分组后我们在对这个分组执行查看长度的操作,实现上述 aggregate 中的第二层分组。go 语言示例代码如下:
var itotal int = 0var res []stringerr := database.C(col.name).Find(find).Distinct("merId", &res)if err != nil {log.Errorf("fail: %s", err)}itotal = len(res)total.Value = itotal
这段代码实现的功能和上述 aggregate 实现的功能是一样的,但它是在从库执行。美中不足的是要把所有符合条件的 merId 都从数据库拉到应用,之后由应用计算其长度,因为 Distinct 返回的结果是一个 error 接口,不能够计算 merId 集合的长度,但牺牲的这点应用内存和应用数据库带宽能换来 mongo 副本集主从库的读写分离,还是值得的。
0 0
- mongoDB 性能优化:如何使用普通查询语句替代 aggregate 操作?
- 使用java 操作mongodb的aggregate
- MongoDb的普通查询操作
- MongoDb的普通查询操作
- mongodb aggregate 级联查询
- mongodb aggregate 聚合操作
- mongodb聚合函数aggregate操作 分组分页查询统计
- Java中使用mongodb的aggregate聚合查询
- 优化SQL查询:如何写出高性能SQL语句
- 优化SQL查询:如何写出高性能SQL语句1
- 优化SQL查询:如何写出高性能SQL语句
- 优化SQL查询:如何写出高性能SQL语句
- 优化SQL查询:如何写出高性能SQL语句
- 优化SQL查询:如何写出高性能SQL语句
- 优化SQL查询:如何写出高性能SQL语句
- 优化SQL查询:如何写出高性能SQL语句
- SQL 优化SQL查询:如何写出高性能SQL语句
- 优化SQL查询:如何写出高性能SQL语句
- Java ThreadManager(线程池管理类)-网络频繁访问处理机制
- 【算法】—— str2int(正序和逆序)
- Git 的origin和master分析
- 关于问题描述的重要性
- LeetCode 171 -Excel Sheet Column Number ( JAVA )
- mongoDB 性能优化:如何使用普通查询语句替代 aggregate 操作?
- 简单的动态规划 Max Sum
- CPPCOREGUIDELINES 异常处理
- imageLoder的初始化配置
- 【剑指offer】二维数组中的查找
- mysql中视图更新详解
- 获取用户最后点击视图(UIWindow的封装)
- CSP考试 2015年03月第3题 节日 C语言实现
- 力控调用OPC采集西门子SMART200PLC数据