如何提高 Raven DB 查询性能?

4

能否有人帮我加速这个查询?我正在使用RavenDB 3.5.8,以下查询需要相当长的时间(在首次加载时尤其如此):

var query = session
                .Query<Card>()
                .Include(p => p.AuthorId)
                .Include(p => p.CompanyId)
                .Where(x => !x.Id.StartsWith("Archived"))
                .Where(x => !x.IsDeleted);

do
{
    var popStash = stashedResults != null && stashedResults.Count > 0;
    if (popStash)
    {
        stashSkip = stashedResults.Count;
    }

    results = query
        .Statistics(out stats)
        .OrderByDescending(x => x.ModifiedAt)
        .Skip(this.ServerPage * this.ServerPageSize)
        .Take(this.ServerPageSize)
        .Select(MapCard)
        .Where(x => x.IsAuthorized)
        .Skip(clientPage * command.PageSize)
        .Take(command.PageSize - stashSkip)
        .ToList();

    if (popStash)
    {
        results = results.Union(stashedResults).ToList();
        stashedResults.Clear();
    }

    if (results.Count < command.PageSize)
    {
        ++this.ServerPage;
        clientPage = 0;

        if (results.Count > 0)
        {
            stashedResults = results;
        }
    }
    

} while (results.Count < command.PageSize &&
    stats.TotalResults >= (this.ServerPage * this.ServerPageSize) + this.ServerPageSize);

我知道这还远非完美,但需要注意的是,由于RavenDB默认不支持认证,所以双重SkipTake是必要的。因此,我必须使用以下代码段对每个卡片进行Map并添加IsAuthorized字段:

IsAuthorized = session.Advanced.IsOperationAllowedOnDocument("Authorization/Users/" + user.Id, "Cards/View", card.Id).IsAllowed;

基本上发生的情况是,首先查询会加载一堆卡片(实际上 ServerPageSize 定义了那么多张卡片)而不考虑安全性,稍后当应用安全控制时,command.PageSize 张卡片就会被加载。(这个网页会动态地加载卡片——首先加载50张卡片,当浏览完后再抓取另外50张,以此类推……)。

请问有人能给我一些提示,如何提高我的代码性能?

1个回答

0

你应该能够使用流式支持来避免多次查询。

你还在负面查询,最好的方法是查询一些正面的内容然后再否定。

请注意,这意味着你正在运行一个非常昂贵的SELECT N+1,对于每个结果,你都会得到一个查询。

为什么不使用授权包查询过滤功能呢?

请参阅此处的文档:

https://ravendb.net/docs/article-page/3.5/Csharp/server/bundles/authorization#operations

你忘记调用 SecureFor 方法了

你可以使用以下代码:

session.SecureFor("Authorization/Users/" + user.Id, "Cards/View");

现在RavenDB将在服务器端执行过滤。


是的,但我不能同时使用授权包和分页。RavenDB鼓励您使用分页。这就是为什么有统计机制,可以返回总数。到目前为止还好。但是当您想要获取统计信息(总数)时,它将跳过授权。 请参见以下链接:
  • https://groups.google.com/g/ravendb/c/YrEulS6xwP8
  • https://dev59.com/7G_Xa4cB1Zd3GeqP2Idt
- csuvikv
由于总项目数未知,查询将起作用并过滤掉不相关的数据。 - Ayende Rahien
是的,过滤器,但不考虑授权。这是我的主要问题。 - csuvikv
很抱歉,你不能两者兼得。一般来说,在授权查询中,你可以避免显示项目的总数。 - Ayende Rahien
我曾经担心我做不到。根据我的经验,我认为我也不能告诉ravenDB我想要下一个50个文档,而我有权查看这些文档。因此,授权只能在加载文档后应用(在这种情况下,session.SecureFor似乎无法工作)。 - csuvikv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接