为什么 $nin 比 $in 慢,Mongodb

问题描述 投票:0回答:3

我收集了 500 万个具有正确索引的文档。$ 工作完美,但相同的查询 $nin 超级慢......这是什么原因?

超快:

{'tech': {'$in': ['Wordpress', 'wordpress', 'WORDPRESS']}}

超级慢..

{'tech': {'$nin': ['Wordpress', 'wordpress', 'WORDPRESS']}}
mongodb performance mongodb-query pymongo
3个回答
4
投票

以下解释仅适用于 3.2 之前的 Mongo 版本

Mongo v3.2 进行了各种存储引擎更改,提高了在此问题上的性能。

现在

$nin
哈希一个重要的品质,这不是一个选择性查询吗,首先让我们了解一下选择性意味着什么:

选择性是查询使用索引缩小结果范围的能力。有效索引更具选择性,允许 MongoDB 使用索引来完成与完成查询相关的大部分工作。

现在他们甚至自己声明:

例如,不等运算符 $nin 和 $ne 的选择性不是很强,因为它们通常匹配索引的很大一部分。因此,在许多情况下,带有索引的 $nin 或 $ne 查询的性能可能并不比必须扫描集合中所有文档的 $nin 或 $ne 查询好。

当时

selectivity
对于性能来说是一件大事。这一切都引出了您的问题,为什么不使用索引?

当 Mongo 被要求创建一个查询计划时,他会在所有可用查询计划之间进行“竞赛”,其中一个是

COLSCAN
,即集合扫描,第一个找到 101 个文档的计划获胜。由于非选择性查询的效率很低,获胜计划(实际上通常更快,具体取决于查询中的索引和值)是
COLSCAN
,请在here

进一步了解这一点

3
投票

当你有索引时(无论你谈论 MongoDB 还是任何其他数据库),搜索某个值总是比搜索不存在的值更快。

数据库必须扫描整个索引,当您查找“not in”或“not equal”时,通常甚至不使用索引。使用

explain()

查看执行计划

一些数据库(例如 Oracle)提供所谓的位图索引。它们的工作方式不同,通常

IN
操作与
NOT IN
操作一样快。但是,与往常一样,与 B*Tree 索引相比,它们还有其他缺点。据我所知,Oracle 数据库是唯一支持位图索引的主要 RDBMS。


0
投票

如果 $nin 或 $ne 仅包含一个值,为什么他们需要扫描记录。

例如: 用户 |已付 1 |是 2 | N

如果我问 ispayed != 'Y',他们仍然可以扫描索引并做出决定,对吗?

© www.soinside.com 2019 - 2024. All rights reserved.