从 CommonPart 访问信息非常慢? [英] Accessing info from CommonPart is extremely slow?

查看:50
本文介绍了从 CommonPart 访问信息非常慢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Orchard 的新手,这一定涉及到底层数据的存储方式.

I'm new to Orchard and this must be something involving how the underlying data is stored.

CommonPart 的连接看起来已经够快了,就像这样:

The joining with CommonPart seems fast enough, like this:

var items = _contentManager.Query<MyUserPart, MyUserPartRecord>("someTypeName")
                           .ForVersion(VersionOptions.Published)
                           .Join<CommonPartRecord>().List().ToList();

运行速度相当快.但是每当我尝试访问 CommonPart 中的某个字段时,它都会像这样运行得非常慢:

That runs fairly fast. But whenever I try accessing some field in CommonPart, it runs extremely slow like this:

var items = _contentManager.Query<MyUserPart, MyUserPartRecord>("someTypeName")
                           .ForVersion(VersionOptions.Published)
                           .Join<CommonPartRecord>().List()
                           //access some field from commonpart
                           .Select(e => new {                               
                               User = e.As<CommonPart>().Owner.UserName
                            }).ToList();

总数据只有1200条左右,需要的时间在5秒左右,不能这么慢.对于后台运行的简单SQL查询,时间应该在0.5秒左右,甚至更短.

The total data is just about 1200 items, and the time it needs is about 5 seconds, it cannot be slow like that. For a simple SQL query run in background, it should take a time of about 0.5 second or even less than.

我曾尝试调查 Orchard 的源代码,但没有发现可能是问题所在.在 IContent 的访问点,一切似乎都进入了一个黑匣子.我希望这里有人能给我一些建议来诊断和解决这个难题.谢谢!

I've tried investigating the Orchard's source code but found nothing that could be the issue. Everything seems to go into a blackbox at the accessing point of IContent. I hope someone here could give me some suggestion to diagnose and solve this hard issue. Thanks!

更新:

我尝试调试了一下,发现在 DefaultContentManager 中命中了以下方法:

I've tried debugging a bit and seen that the following method is hit inside the DefaultContentManager:

ContentItem New(string contentType) { ... }

嗯,这真的很有趣,查询只是请求数据,没有修改、插入和更新任何内容.但是被击中的那个方法表明这里出了点问题.

Well that's really interesting, the query is just asking for data without modifying, inserting and updating anything. But that method being hit shows that something's wrong here.

更新:

根据@Bertrand Le Roy 的评论,我使用 QueryHint 尝试了以下代码,但看起来没有任何改变:

With @Bertrand Le Roy's comment, I've tried the following codes with QueryHint but looks like it does not change anything:

var items = _contentManager.Query<MyUserPart, MyUserPartRecord>("someTypeName")
                           .ForVersion(VersionOptions.Published)
                           .Join<CommonPartRecord>()
                           .WithQueryHints(new QueryHints().ExpandParts<CommonPart>())
                           .List()
                           //access some field from commonpart
                           .Select(e => new {                               
                               User = e.As<CommonPart>().Owner.UserName
                            }).ToList();

还有这个(没有.Join)

var items = _contentManager.Query<MyUserPart, MyUserPartRecord>("someTypeName")
                           .ForVersion(VersionOptions.Published)
                           .WithQueryHints(new QueryHints().ExpandParts<CommonPart>())
                           .List()
                           //access some field from commonpart
                           .Select(e => new {                               
                               User = e.As<CommonPart>().Owner.UserName
                            }).ToList();

推荐答案

Select 访问 Owner 属性会导致 CommonPartHandler 中的延迟加载器> 要求内容管理器加载用户内容项:_contentManager.Get(part.Record.OwnerId).根据您的查询结果,每个内容项都会发生一次,因此会导致选择 n+1,其中 n = 1200.

Accessing the Owner property from your Select causes the lazy loader in CommonPartHandler to ask the content manager to load the user content item: _contentManager.Get<IUser>(part.Record.OwnerId). This happens once per content item result from your query, so results in a select n+1 where n = 1200 according to your question.

至少有两种方法可以避免这种情况:

There are at least two ways of avoiding that:

  1. 您可以使用 HQL 并制作一个查询,在 1 次操作中预先为您提供所需的一切.
  2. 您可以进行第一个内容管理器查询以获取所有者 ID 集,然后对这些 ID 进行第二次内容管理器查询,并通过总共 2 次而不是 1201 次查询获得所需的一切.

这篇关于从 CommonPart 访问信息非常慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆