使用分页时的 Documentdb 性能
Documentdb performance when using pagination
我有一个关于分页的工作代码,它适用于 azure 搜索和 sql,但是在 documentdb 上使用它时,加载最多需要 60 秒。
我们认为这是一个延迟问题,但我找不到解决方法来解决它,
关于从哪里开始寻找的任何文档或想法?
public PagedList(IQueryable<T> superset, int pageNumber, int pageSize, string sortExpression = null)
{
if (pageNumber < 1)
throw new ArgumentOutOfRangeException("pageNumber", pageNumber, "PageNumber cannot be below 1.");
if (pageSize < 1)
throw new ArgumentOutOfRangeException("pageSize", pageSize, "PageSize cannot be less than 1.");
// set source to blank list if superset is null to prevent exceptions
TotalItemCount = superset == null ? 0 : superset.Count();
if (superset != null && TotalItemCount > 0)
{
Subset.AddRange(pageNumber == 1
? superset.Skip(0).Take(pageSize).ToList()
: superset.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList()
);
}
}
虽然 DocumentDB 的 LINQ 提供程序在某些情况下将 .Take() 转换为 "TOP" SQL 子句,但 DocumentDB 没有 Skip 的等效项。所以,我对它的工作原理感到有点惊讶,但我怀疑提供者正在从头开始重新运行查询以模拟 Skip。在评论 here 中,DocumentDB 产品经理就他们选择不实施 SKIP 的原因进行了讨论。 TL;博士;它不适用于 NoSQL 个数据库。我可以用 MongoDB 确认这一点(它确实具有跳过功能)。后面的页面只需扫描并丢弃前面的文档。在列表中越靠后,它变得越慢。我怀疑 LINQ 实现在做类似的事情,除了客户端。
DocumentDB 确实有一种以块的形式获取文档的机制,但它的工作方式与 SKIP 略有不同。它使用延续标记。您甚至可以设置 maxPageSize,但是不能保证您会取回该数字。
我建议您实现自己的客户端缓存并使用相当大的 maxPageSize。假设您 UI 中的每个页面有 10 行,而您的缓存当前有 27 行。如果用户 select 的第 1 页或第 2 页,您有足够的行来呈现已缓存数据的结果。如果用户 select 第 7 页,那么您知道缓存中至少需要 70 行。使用最后一个继续令牌获取更多,直到缓存中至少有 70 行,然后呈现第 61-70 行。从好的方面来说,延续令牌的寿命很长,因此您可以稍后根据用户输入使用它们。
我有一个关于分页的工作代码,它适用于 azure 搜索和 sql,但是在 documentdb 上使用它时,加载最多需要 60 秒。
我们认为这是一个延迟问题,但我找不到解决方法来解决它,
关于从哪里开始寻找的任何文档或想法?
public PagedList(IQueryable<T> superset, int pageNumber, int pageSize, string sortExpression = null)
{
if (pageNumber < 1)
throw new ArgumentOutOfRangeException("pageNumber", pageNumber, "PageNumber cannot be below 1.");
if (pageSize < 1)
throw new ArgumentOutOfRangeException("pageSize", pageSize, "PageSize cannot be less than 1.");
// set source to blank list if superset is null to prevent exceptions
TotalItemCount = superset == null ? 0 : superset.Count();
if (superset != null && TotalItemCount > 0)
{
Subset.AddRange(pageNumber == 1
? superset.Skip(0).Take(pageSize).ToList()
: superset.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList()
);
}
}
虽然 DocumentDB 的 LINQ 提供程序在某些情况下将 .Take() 转换为 "TOP" SQL 子句,但 DocumentDB 没有 Skip 的等效项。所以,我对它的工作原理感到有点惊讶,但我怀疑提供者正在从头开始重新运行查询以模拟 Skip。在评论 here 中,DocumentDB 产品经理就他们选择不实施 SKIP 的原因进行了讨论。 TL;博士;它不适用于 NoSQL 个数据库。我可以用 MongoDB 确认这一点(它确实具有跳过功能)。后面的页面只需扫描并丢弃前面的文档。在列表中越靠后,它变得越慢。我怀疑 LINQ 实现在做类似的事情,除了客户端。
DocumentDB 确实有一种以块的形式获取文档的机制,但它的工作方式与 SKIP 略有不同。它使用延续标记。您甚至可以设置 maxPageSize,但是不能保证您会取回该数字。
我建议您实现自己的客户端缓存并使用相当大的 maxPageSize。假设您 UI 中的每个页面有 10 行,而您的缓存当前有 27 行。如果用户 select 的第 1 页或第 2 页,您有足够的行来呈现已缓存数据的结果。如果用户 select 第 7 页,那么您知道缓存中至少需要 70 行。使用最后一个继续令牌获取更多,直到缓存中至少有 70 行,然后呈现第 61-70 行。从好的方面来说,延续令牌的寿命很长,因此您可以稍后根据用户输入使用它们。