搜索简单的实体关系非常慢

时间:2012-02-21 21:31:41

标签: dynamics-crm dynamics-crm-4

我们在我们的机构使用CRM 4.0,并且没有计划进行升级,因为我们花了一年半的时间来定制和扩展CRM以使用我们的流程。

模型的一小部分是简单的层次结构,我们有一组学习室,与另一个实体有一对多的关系,描述了该学习室可用的课程。 另一个实体列出了所有已表达对任何课程感兴趣的潜在和注册学生。

这一点很简单,效果很好,并且被模拟为3个自定义实体。

现在,我们有一个管理员应用程序,可以读取房间,然后想要显示该房间的课程,但仅限于有注册学生的地方。

在SQL中,这简化为:

SELECT DISTINCT r.CourseName, r.OtherInformation
FROM Rooms r
  INNER JOIN Students S
    ON S.CourseId = r.CourseId
WHERE r.RoomId = @RoomId

这确实非常接近CRM生成的最终SQL。 我们使用Crm QueryEntity,Filter和LinkEntity来表示相同的结构。

现在的问题是,CRM将自定义实体规范化为基表,该基表具有所有共享的标准CRM实体数据,然后是具有我们自定义的ExtensionBase表。要对此进行展平访问,它会创建一个合并两个表的视图。 此视图是Generated SQL使用的视图。

现在基表有索引,但视图没有。

我们遇到的问题是,我们要做的就是返回满足内连接的课程,这足以证明有条目和CRM使它成为SELECT DISTINCT,所以我们只为Room提供一个项目。 起初这很好用,但现在我们有成千上万的查询,它需要超过30秒,当然除了短信之外什么都会导致超时。

我相信我们可以在CRM中创建和更改表格中的索引,并且这些索引不被认为是不受支持的修改;观点怎么样? 我知道如果我们改变一个实体,那么它的视图会被重新创建,这当然会让我们在发生这种情况时重做我们的索引。

有没有办法提示CRM4.0我们想要一个特定的索引?

另一位消息人士建议,如果遇到这样的问题,最好将数据放在一起,但这并不是我在尝试设计解决方案时感到舒服的事情。

我曾考虑过将一个新实体放入其中,只有RoomId,CourseId和Enrollment Count,但是那也是非常hacky;毕竟,索引将解决复制此数据的需要,并具有某种触发器,可在每次学生操作后更新数据。

最后,虽然我知道目前我们仍然坚持使用CRM4,但这是否是我们可以期待在CRM2011中解决的问题?这肯定会增加这个5年历史产品升级的重要性。

3 个答案:

答案 0 :(得分:1)

Someone asked a similar question here我认为没有确凿的答案。引用的微软问题是参考完整性(这里不是问题)和升级并发症。您提到了不受支持的选项,即添加视图并通过升级和实体更改对其进行管理。这是一个选择,因为它不应该支持和黑客,它应该工作。

FetchXml确实有聚合,但查询执行计划仍然使用视图:这是从事件的简单选择计数生成的SQL:

'select 
top 5000 COUNT(*) as "rowcount"
, MAX("__AggLimitExceededFlag__") as "__AggregateLimitExceeded__" from (select top 50001 case when ROW_NUMBER() over(order by (SELECT 1)) > 50000 then 1 else 0 end as "__AggLimitExceededFlag__" from Incident as "incident0"  ...

我没有看到针对您的问题的受支持解决方案。

如果您正在构建外部管理应用程序并且您在本地托管CRM 4,则可以直接转到数据库以绕过CRM API进行查询。不支持,但可以让您解决问题。

答案 1 :(得分:1)

由于视图是“动态的”(从概念上讲,它们的内容是每次使用时从基表中即时生成的),因此它们通常无法编入索引。但是,SQL Server确实支持称为“索引视图”的东西。您需要在视图上创建唯一的聚簇索引,查询分析器应该能够使用它来加速您的连接。

答案 2 :(得分:0)

我打算将此作为一个潜在的答案,尽管我不相信它是一个可持续的或确实有效的长期解决方案。

在分析了CRM自动定义的索引之后,我意识到在我的查询中选择更多信息就足以满足索引的列要求,现在查询运行的时间不到一秒。