joh*_*odo 104 sorting indexing performance query-optimization mongodb
引用文档:
创建索引时,与键关联的数字指定索引的方向,因此它应始终为1(升序)或-1(降序).方向对于单个键索引或随机访问检索无关紧要,但如果您对复合索引进行排序或范围查询,则该方法很重要.
但是,我认为没有理由为什么指数的方向应该对复合指数起作用.有人可以提供进一步的解释(或示例)吗?
Jar*_*lls 101
MongoDB以某种方式连接复合密钥,并将其用作BTree中的密钥.
查找单个项目时 - 树中节点的顺序无关紧要.
如果要返回一系列节点 - 彼此靠近的元素将位于树的相同分支下方.节点越接近范围,它们就越快被检索.
使用单个字段索引 - 顺序无关紧要.如果它们按升序排列在一起,它们也将按降序排列在一起.
当你有一个复合键 - 顺序开始重要.
例如,如果键是A升序B升序索引可能看起来像这样:
Row A B 1 1 1 2 2 6 3 2 7 4 3 4 5 3 5 6 3 6 7 5 1
对于升序B降序的查询将需要不按顺序跳转索引以返回行并且将更慢.例如,它将返回Row1, 3, 2, 6, 5, 4, 7
与索引顺序相同的远程查询将以正确的顺序依次返回行.
在BTree中查找记录需要O(Log(n))时间.按顺序查找记录范围仅为OLog(n)+ k,其中k是要返回的记录数.
如果记录乱序,则成本可能与OLog(n)*k一样高
Zai*_*sud 42
您正在寻找的简单答案是,当您在两个字段上进行排序时,方向才重要.
如果你正在排序{a : 1, b : -1}:
索引{a : 1, b : 1}将慢于索引{a : 1, b : -1}
Som*_*luk 10
理解两个关键点.
索引不是免费的.它们占用内存,并在执行插入,更新和删除时强加性能损失.通常,性能损失可以忽略不计(特别是与读取性能的提升相比),但这并不意味着我们无法聪明地创建索引.
确定应将哪些字段组合在一起是为了了解您正在运行的查询.用于创建索引的字段顺序非常重要.好消息是,如果您的订单错误,索引将根本不会被使用,因此很容易发现解释.
您的查询可能需要排序.但是排序可能是一项昂贵的操作,因此处理您正在排序的字段非常重要,就像您要查询的字段一样.所以如果它有索引会更快.但是有一个重要的区别,您要排序的字段必须是索引中的最后一个字段.此规则的唯一例外是,如果该字段也是查询的一部分,则必须是最后一条规则不适用.
您可以在索引的所有键或子集上指定排序; 但是,排序键必须按它们在索引中显示的顺序列出.例如,索引键模式{a:1,b:1}可以支持{a:1,b:1}上的排序,但不能支持{b:1,a:1}上的排序.
排序必须为其所有键指定相同的排序方向(即升序/降序)作为索引键模式,或者为其所有键指定反向排序方向作为索引键模式.例如,索引键模式{a:1,b:1}可以支持对{a:1,b:1}和{a:-1,b:-1}的排序,但不支持{a:-1上的排序,b:1}.
假设有这些索引:
{ a: 1 }
{ a: 1, b: 1 }
{ a: 1, b: 1, c: 1 }
Example Index Used
db.data.find().sort( { a: 1 } ) { a: 1 }
db.data.find().sort( { a: -1 } ) { a: 1 }
db.data.find().sort( { a: 1, b: 1 } ) { a: 1, b: 1 }
db.data.find().sort( { a: -1, b: -1 } ) { a: 1, b: 1 }
db.data.find().sort( { a: 1, b: 1, c: 1 } ) { a: 1, b: 1, c: 1 }
db.data.find( { a: { $gt: 4 } } ).sort( { a: 1, b: 1 } ) { a: 1, b: 1 }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19909 次 |
| 最近记录: |