为什么 $nin 比 $in 慢,Mongodb
Why $nin is slower than $in, Mongodb
我收集了 500 万个具有正确索引的文档。$ 工作完美,但与 $nin 的相同查询超级慢...这是什么原因?
超级快:
{'tech': {'$in': ['Wordpress', 'wordpress', 'WORDPRESS']}}
超级慢..
{'tech': {'$nin': ['Wordpress', 'wordpress', 'WORDPRESS']}}
当你有索引时(无论你谈论 MongoDB 还是任何其他数据库),搜索某个值总是比搜索 non-existing 值更快。
数据库必须扫描整个索引,当您查找“不在”或“不等于”时,通常甚至没有使用索引。使用 explain()
查看执行计划
一些数据库(例如 Oracle)提供所谓的位图索引。它们的工作方式不同,通常 IN
操作与 NOT IN
操作一样快。但是,和往常一样,与 B*Tree 索引相比,它们还有其他缺点。据我所知,Oracle 数据库是唯一支持位图索引的主要 RDBMS。
以下解释仅适用于 Mongo 3.2
之前的版本
Mongo v3.2 对存储引擎进行了各种更改,改进了此问题的性能。
现在 $nin
哈希一个重要的质量,它不是 selective query, First let's understand what selectivity 意味着:
Selectivity is the ability of a query to narrow results using the index. Effective indexes are more selective and allow MongoDB to use the index for a larger portion of the work associated with fulfilling the query.
现在他们自己也说了:
For instance, the inequality operators $nin and $ne are not very selective since they often match a large portion of the index. As a result, in many cases, a $nin or $ne query with an index may perform no better than a $nin or $ne query that must scan all documents in a collection.
那时候 selectivity
在性能方面很重要。这一切都引出了您的问题,为什么没有使用索引?
好吧,当 Mongo 被要求创建一个查询计划时,他会在所有可用的查询计划之间进行“竞赛”,其中一个是 COLSCAN
即集合扫描,其中第一个计划找到101 份文件获胜。由于 non-selective 查询的效率低下(实际上通常更快,具体取决于查询中的索引和值)是 COLSCAN
,请进一步阅读 here
我收集了 500 万个具有正确索引的文档。$ 工作完美,但与 $nin 的相同查询超级慢...这是什么原因?
超级快:
{'tech': {'$in': ['Wordpress', 'wordpress', 'WORDPRESS']}}
超级慢..
{'tech': {'$nin': ['Wordpress', 'wordpress', 'WORDPRESS']}}
当你有索引时(无论你谈论 MongoDB 还是任何其他数据库),搜索某个值总是比搜索 non-existing 值更快。
数据库必须扫描整个索引,当您查找“不在”或“不等于”时,通常甚至没有使用索引。使用 explain()
一些数据库(例如 Oracle)提供所谓的位图索引。它们的工作方式不同,通常 IN
操作与 NOT IN
操作一样快。但是,和往常一样,与 B*Tree 索引相比,它们还有其他缺点。据我所知,Oracle 数据库是唯一支持位图索引的主要 RDBMS。
以下解释仅适用于 Mongo 3.2
之前的版本Mongo v3.2 对存储引擎进行了各种更改,改进了此问题的性能。
现在 $nin
哈希一个重要的质量,它不是 selective query, First let's understand what selectivity 意味着:
Selectivity is the ability of a query to narrow results using the index. Effective indexes are more selective and allow MongoDB to use the index for a larger portion of the work associated with fulfilling the query.
现在他们自己也说了:
For instance, the inequality operators $nin and $ne are not very selective since they often match a large portion of the index. As a result, in many cases, a $nin or $ne query with an index may perform no better than a $nin or $ne query that must scan all documents in a collection.
那时候 selectivity
在性能方面很重要。这一切都引出了您的问题,为什么没有使用索引?
好吧,当 Mongo 被要求创建一个查询计划时,他会在所有可用的查询计划之间进行“竞赛”,其中一个是 COLSCAN
即集合扫描,其中第一个计划找到101 份文件获胜。由于 non-selective 查询的效率低下(实际上通常更快,具体取决于查询中的索引和值)是 COLSCAN
,请进一步阅读 here