mongodb - 为什么当条目已经排序时,mongo 不会用 SORT_MERGE 阶段替换 OR 阶段
问题描述
我有一个包含以下两个索引的集合:{ tags: 1, views: 1 }
和{ author.username'': 1, views: 1 }
我正在寻找一种以最优化的方式获取以下查询结果的方法
searchArray = ['exam', 'ple', 'dot', 'com']
collection.find({
$or: [
{ tags: { $all: searchArray } },
{ 'author.username': { $in: searchArray } }
]
}).sort({ views: -1 }).limit(10).explain()
// it takes ~0.05ms with ~150 000 entries
对于先前的请求,查询计划器由于 SORT 阶段而没有给出合适的解决方案。
但是,如果我们单独删除 $ 或每个请求,速度非常快且没有 SORT 阶段。
searchArray = ['exam','ple','dot','com']
collection.find({
tags: { $all: searchArray }
}).sort({ views: -1 }).limit(10).explain()
// it takes ~0.002ms with ~150 000 entries
searchArray = ['exam','ple','dot','com']
collection.find({
'author.username': { $in: searchArray }
}).sort({ views: -1 }).limit(10).explain()
// it takes ~0.003ms with ~150 000 entries
所以在单个查询中我们没有 SORT 阶段,这意味着数据已经使用索引进行了排序,那么为什么查询计划器不使用 SORT_MERGE 阶段而不是 OR 阶段呢?
解决方案
首先,你真的很幸运 aSORT_MERGE
正在发生。通常,当您应用使用索引第一部分的 RANGE 查询(您的$in
or $all
)时,使用索引SORT
的第二部分不会发生 a 。因为您正在探索的索引的 B 树的每个分支彼此之间没有排序。这里SORT_MERGE
实际上是将 B 树的这些分支合并为一个结果。
在您的情况下,第一个查询的问题是您希望SORT_MERGE
彼此之间有两个完全不同的索引。这绝对是不可能的。SORT_MERGE
只有当您多次使用相同的索引时才会发生这种情况。
因此,在您的情况下,我建议您仅在该views
字段上实际创建索引。至少它应该加快排序。
推荐阅读
- jquery - jquery_jeditable:控制来自先例输入的最大数量
- javascript - 在 Vue 应用程序中,Key Up 事件在输入元素上触发。为什么?
- php - Laravel - 无法打开流:没有这样的文件或目录存储/框架/会话
- json - 颤振 - 错误:“Articles”类型的值不能分配给“int”类型的变量
- jquery - 调用函数时服务器端数据表 ajax 返回“数据表警告:表 id=tblDataTable - 无效的 JSON 响应。”
- php - 通过 PHP 中的 Graph API 发布到 Instagram
- ruby - 将数字变成红宝石中的分数?
- tabulator - 制表符 - 布局选项
- html - 将两个图像放在另一个之上
- sql-server - 在 Azure Pipeline 中构建数据库项目时如何替换 SQL 脚本中的数据库引用