当查询集合中的可选键时,以下两个查询的性能会有所不同。
良好的响应:当使用特定值(除 null 之外的值)进行查询时,会产生良好的响应时间。
因此我请求您能解释一下造成这种性能差异的原因,这将有助于我增加和确认我的理解。
馆藏统计
两个查询:
查询 1 - 响应时间良好
索引(更准确地说是 B*Tree 索引)是所有值的
排序列表。因此,在您的情况下,索引包含值 undefined
或类似值的 100k 倍。您必须读取所有这些值才能确定该值是否未定义。在另一种情况下,当您查找
some_value
时,您在从索引中读取第一个条目后就已经知道结果了,因为如果该值存在,它会出现在第一个
undefined
值之前。上面的解释不要太字面意思,它只是说明了原理。
请注意,如果值不存在,许多数据库不会在索引中存储任何值。在您的情况下,索引大小将为 0 字节。在这样的数据库中,您的索引将毫无用处。但是,MongoDB 还在索引中存储未定义的值。
可选键上的索引已完成: 它是完整的,因为索引和集合中的文档数量将相同。还需要注意的是,对于该键为“不存在”或“空”的文档也将包含在索引中。这种索引背后的原因是默认情况下索引是非唯一的,或者换句话说,重复的键值也包含在索引中。
现在开始这个案例:
在这种情况下,可选键是“field_A”。让我们看一个样本集合如下。它有 4 个文档,键“field_A”上的索引也将有 4 个文档。 3 个文档在相同的值下建立索引 - null 和 1 个文档的值为 1。此行为已在手册中的“稀疏索引”部分中进行了解释:
Sample collection :
[
{ field_A: 1, field_B: ‘a’ },
{ field_B: ‘b’ },
{ field_B: ‘c’ },
{ field_B: ‘d’ } ]
Sample index - field_A :
[ { field_A: null } pointed to the document { field_B: ‘a’ } ,
{ field_A: null } pointed to the document { field_B: ‘b’ } ,
{ field_A: null } pointed to the document { field_B: ‘c’ } ,
{ field_A: 1 } pointed to the document { field_A: 1, field_B: ‘d’ } ]
第一个查询 - { field_A: "some_value" }现在此上下文下的查询 { field_A: "some_value" } 将由该索引支持。在示例案例中,在查询值 1 时,由于索引是有序的,因此它将快速找到值 1 并返回文档。因此这个查询应该是高性能的。
第二个查询 - { field_A: { $exists: true } }
此查询不会使用此索引,因此它将执行集合扫描。因此这需要时间。 不使用索引的原因已在手册“$exists”部分中解释如下:
“在使用非稀疏索引的字段上使用 { $exists: true } 的查询或在未索引的字段上使用 { $exists: true } 的查询会检查集合中的所有文档。”
在这种情况下,不会使用索引,因为该索引是非稀疏索引。此查询需要稀疏索引。
稀疏索引
https://www.mongodb.com/docs/manual/core/index-sparse/#std-label-index-type-sparse:~:text=%E2%86%92%20MongoDB%20Manual-,Sparse% 20 个索引,-稀疏%20 个索引%20only
$存在https://www.mongodb.com/docs/manual/reference/operator/query/exists/#:~:text=a%20FETCH.-,Queries%20that%20use,-%7B%20%24exists%3A %20true%20%7D
谢谢 我们做最好的4你