为啥 $nin 比 $in 慢,Mongodb
Posted
技术标签:
【中文标题】为啥 $nin 比 $in 慢,Mongodb【英文标题】:Why $nin is slower than $in, Mongodb为什么 $nin 比 $in 慢,Mongodb 【发布时间】:2021-01-15 05:58:56 【问题描述】:我收集了具有正确索引的 5M 文档。$in 工作完美,但相同的查询 $nin 超级慢...这是什么原因?
超快:
'tech': '$in': ['Wordpress', 'wordpress', 'WORDPRESS']
超级慢..
'tech': '$nin': ['Wordpress', 'wordpress', 'WORDPRESS']
【问题讨论】:
【参考方案1】:以下解释仅适用于 3.2 之前的 Mongo 版本
Mongo v3.2 对存储引擎进行了各种更改,从而提高了该问题的性能。
现在$nin
哈希一个重要的质量,它不是selective 查询,首先让我们了解selectivity 的含义:
选择性是查询使用索引缩小结果的能力。有效的索引更具选择性,允许 MongoDB 将索引用于与完成查询相关的大部分工作。
现在他们甚至自己声明:
例如,不等式运算符 $nin 和 $ne 不是很有选择性,因为它们通常匹配索引的大部分。因此,在许多情况下,带有索引的 $nin 或 $ne 查询的性能可能并不比必须扫描集合中所有文档的 $nin 或 $ne 查询好。
当时selectivity
在性能方面非常重要。这一切都引出了您的问题,为什么不使用索引?
好吧,当 Mongo 被要求创建一个查询计划时,他会在所有可用的查询计划之间进行“竞赛”,其中一个是 COLSCAN
即集合扫描,其中找到 101 个文档的第一个计划获胜。由于非选择性查询的效率低下,获胜计划(实际上通常更快,具体取决于查询中的索引和值)是COLSCAN
,进一步了解此here
【讨论】:
$nin 的速度和 $in 一样的方法是什么?也许有一些技巧? 在 3.2 之前的 Mongo 版本中,这永远不会发生,在更新的版本中,我会说它严重依赖于您排除的值和索引树的结构。仍然无法在性能方面比较两者。【参考方案2】:当您有索引时(无论您谈论的是 MongoDB 还是任何其他数据库),搜索某个值总是比搜索不存在的值更快。
数据库必须扫描整个索引,当您查找“不在”或“不等于”时,通常甚至没有使用索引。用explain()
查看执行计划
一些数据库(例如 Oracle)提供所谓的位图索引。它们的工作方式不同,通常IN
操作与NOT IN
操作一样快。但是,像往常一样,与 B*Tree 索引相比,它们还有其他缺点。据我所知,Oracle 数据库是唯一支持位图索引的主要 RDBMS。
【讨论】:
以上是关于为啥 $nin 比 $in 慢,Mongodb的主要内容,如果未能解决你的问题,请参考以下文章