为啥 $nin 比 $in 慢,Mon​​godb

Posted

技术标签:

【中文标题】为啥 $nin 比 $in 慢,Mon​​godb【英文标题】:Why $nin is slower than $in, Mongodb为什么 $nin 比 $in 慢,Mon​​godb 【发布时间】: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 慢,Mon​​godb的主要内容,如果未能解决你的问题,请参考以下文章

为啥整数上的 in_array 严格模式比非严格模式慢?

为啥在 SQL 查询中 NOT IN 比 IN 慢得多

为啥 byte 的工作速度比 int 慢?类实例化

为啥向量总是比 C 数组慢,至少在这种情况下?

为啥并行多线程代码执行比顺序慢?

为啥 python gevent 比串行慢?