如何加快 Raven DB 查询性能?

时间:2021-03-01 15:08:10

标签: c# ravendb

谁能帮我加快查询速度?我正在使用 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);

我知道它远非完美,但请注意双 SkipTake 是必要的,因为 RavenDB 默认不支持身份验证,所以我必须 {{1} } 每张卡片,并使用以下代码段向其中添加 Map 字段:

IsAuthorized

基本上发生的事情是首先查询加载一堆卡片(实际上 ServerPageSize 定义了那里的卡片数量)而不考虑安全性,然后在应用安全性时加载 IsAuthorized = session.Advanced.IsOperationAllowedOnDocument("Authorization/Users/" + user.Id, "Cards/View", card.Id).IsAllowed; 卡片。 (网页动态加载卡片 - 加载前 50 张卡片,查看这些卡片后,将抓取另外 50 张卡片,依此类推。)。

有人可以给我提示如何提高我的代码的性能吗?

1 个答案:

答案 0 :(得分: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 将负责过滤服务器端。