大概的查询语句
集合schema
{
//...省略其他字段
"_id": ObjectId("65e9310b6c21fc6df939c43d"),
"nodeType": "start",
"executeTime": ISODate("2024-03-07T03:14:19.708Z"),
"isDetail": false,
}
索引
{
"executeTime": -1,
"nodeType": 1,
"isDetail": 1,
}
查询语句
db.collection.countDocuments({
"executeTime": {
$gte: new Date(new Date().getTime() - 30 * 24 * 60 * 60 * 1000),
$lte: new Date()
},
"nodeType": "interactive",
"isDetail": true,
}, {
"executeTime": 1
"nodeType": 1,
"isDetail": 1,
"_id": 1,
})
1
Yuan2One 284 天前 via Android
只查总数吗,存 redis 可以吗
|
2
rimutuyuan 284 天前
定时去 count 缓存,这么多数据应该不需要实时精确数量吧?
|
3
coderxy 284 天前
这个要看你索引的定义, 一般 count 条件语句的第一个字段非常重要,要用比较稀疏的字段, 还是要具体分析的。 你可以把你的字段和查询条件贴出来,具体分析一下看看。
|
4
defunct9 284 天前 1
开 ssh ,让我上去看看
|
6
Belmode OP @Yuan2One #1 虽然查询频率很低,但是还是会有条件变化的,redis 不适合这种场景。
@rimutuyuan #2 查询频率很低,但是条件会变化,所以定时任务也不太行 @coderxy #3 查询的第一个条件是时间。 @defunct9 #4 老哥老面孔了 @lilei2023 #5 上面的老哥是来挽尊的,气氛担当~ |
7
Belmode OP @coderxy #3 集合结构和查询语句
集合 schema { //...省略其他字段 "_id": ObjectId("65e9310b6c21fc6df939c43d"), "nodeType": "start", "executeTime": ISODate("2024-03-07T03:14:19.708Z"), "isDetail": false, } 索引 { "executeTime": -1, "nodeType": 1, "isDetail": 1, } 查询语句 db.collection.countDocuments({ "executeTime": { $gte: new Date(new Date().getTime() - 30 * 24 * 60 * 60 * 1000), $lte: new Date() }, "nodeType": "interactive", "isDetail": true, }, { "executeTime": 1 "nodeType": 1, "isDetail": 1, "_id": 1, }) |
8
coderxy 284 天前
@Belmode nodeType 存在的值多不多? 多的话拿 nodeType 做联合索引第一位,isDetail=true 的情况多不多,多的话拿 isDetail 做第一位,反正索引要么是 nodeType_isDetail_executeTime 要么是 isDetail_nodeType_executeTime ,你再去试试,性能应该回好不少。 你现在的索引用法,估计 explain 分析一下,seek 特别多。 最终的效果可能相当于只有 executeTime 单索引的效果。
|
9
rrfeng 284 天前 via Android
这索引没啥可以优化的,只能走预计算了。
比如把每天的 count 算出来单独存一下,这个查询优化成 sum 29 天 统计数据+本日数据。 |
10
mingsz 284 天前
executeTime 需要查询的那么精确吗,可以新增个字段,如果到天/小时,索引会小很多
|
11
ychost 284 天前
这个感觉没太大优化点了,每天提前把所有条件都查一遍吧,然后前端值允许查看预制的筛选条件
|
12
nomagick 284 天前
是不是小内存机械盘?
起码得用个固态盘。。。 |