索引键上的 cursor.skip() 总是更快吗?

Is cursor.skip() on indexed keys always faster?

本文关键字:cursor skip 索引      更新时间:2023-09-26

我有2个数据库:slowfast;每个数据库都有4096个条目。age键是使用以下脚本生成的唯一随机整数:

var arr = []
while(arr.length < 4096){
  var randmnum=Math.ceil(Math.random()*1000000)
  var found=false;
  for(var i=0;i<arr.length;i++){
    if(arr[i]==randmnum){found=true;break}
  }
  if(!found)arr[arr.length]=randmnum;
}
var i=0;
for (i=0 ; i< arr.length; ++i) {
    db.fast.insert({name:"john doe", email:"once@upon.a.time.com", age:arr[i]});
    db.slow.insert({name:"john doe", email:"once@upon.a.time.com", age:arr[i]});
}

然后在蒙戈壳中:

> db.createCollection("slow")
> db.createCollection("fast")
> load("theAboveScript.js")
> db.fast.createIndex({"age":1})

如果我测试findsortfast db 上完成的work量低于预期的slow。此外,索引/快速数据库的执行时间大约快 2 倍。

但是当我执行以下操作时:

> pageNumber=18;nPerPage=20; db.slow.find().skip(pageNumber > 0 ? ((pageNumber-1)*nPerPage) : 0).limit(nPerPage).explain("executionStats")
> pageNumber=18;nPerPage=20; db.fast.find().skip(pageNumber > 0 ? ((pageNumber-1)*nPerPage) : 0).limit(nPerPage).explain("executionStats")
工作量完全相同,

执行时间也差不多,甚至快速数据库也慢了一点。

为什么 cursor.skip() 如果它适用于索引键,它不会得到任何提升?我希望分页返回排序的分页数据,而无需对其进行显式排序。

您的两个查询都没有对age进行过滤,因此没有理由使用该索引。

如果您在 age 上添加条件,也会有所不同(即使文档如此之少,差异很小)

> pageNumber=18;nPerPage=20; db.slow.find({age:{$gt:200}}).
      skip(pageNumber > 0 ? ((pageNumber-1)*nPerPage) : 0).limit(nPerPage).
      explain("executionStats")
# "executionTimeMillis" : 14,
# "inputStage" : {
#     "stage" : "COLLSCAN",
> pageNumber=18;nPerPage=20; db.fast.find({age:{$gt:200}}).
      skip(pageNumber > 0 ? ((pageNumber-1)*nPerPage) : 0).limit(nPerPage).
      explain("executionStats"
# "executionTimeMillis" : 0,
# "inputStage" : {
#     "stage" : "IXSCAN",

如图所示,您在 AGE 字段上有索引,因此按索引字段搜索速度更快。

分页问题来自这样一个事实,即您的查询未被覆盖,这意味着它需要获取完整的文档 - 因此在这种情况下索引不会发挥作用。

请参阅此处以供参考