Dynamics CRM SSRS报表Incident查询性能优化建议咨询
优化Dynamics CRM SSRS报表查询性能的建议
看起来你在Dynamics CRM的SSRS报表查询上遇到了性能瓶颈,我帮你分析下问题并给出针对性的优化建议:
1. 修正子查询逻辑,确保关联正确且高效
你的第一个查询里的子查询逻辑有明显问题:group by createdon,zon_case会把每个不同的日志时间和工单ID组合当成独立分组,再加上top 1只会返回单条记录,根本没法正确关联每个工单对应的最新日志时间。我帮你改写了子查询,确保每个工单只取最新的日志时间:
select ticketnumber, Title, zon_requeststatusname, FI.owneridname, zon_applicationname, zon_applicationareaname, CL.LastLogChanged, zon_requestorname, FI.createdon, FI.createdbyname, isescalatedname, zon_ordername, DATEDIFF(DAY, GETDATE(), FI.createdon) as AgingPeriod from filteredincident FI left outer join ( select zon_case, max(createdon) as LastLogChanged from Filteredzon_caselog group by zon_case -- 只按工单ID分组,精准获取每个工单的最新日志时间 ) CL on FI.incidentid = CL.zon_case where -- 重点:改写日期条件,避免用函数包裹字段,让索引能生效 FI.createdon >= DATEADD(day, -@CreatedInLast, GETDATE()) AND FI.createdon < DATEADD(day, -@CreatedInLast + 1, GETDATE()) AND FI.modifiedon >= DATEADD(day, -@ModifiedSince, GETDATE()) AND FI.modifiedon < DATEADD(day, -@ModifiedSince + 1, GETDATE())
2. 别在WHERE子句里给字段套函数!
原查询里DATEDIFF(day,FI.createdon ,GETDATE()) = @CreatedInLast这种写法是性能杀手——SQL Server没法用createdon字段上的索引(函数会打乱字段的有序性),必须改成直接比较字段和计算好的日期范围,这样数据库才能快速定位符合条件的记录。
3. 给Filtered视图的底层表加合适的索引
既然你不想放弃Filtered视图的安全权限控制,那可以针对它依赖的底层表优化索引:
- 确保
incident表的createdon、modifiedon字段有非聚集索引,或者包含在覆盖索引里(覆盖索引就是把查询需要的字段都包含进去,不用回表查数据) - 给自定义表
zon_caselog建一个覆盖索引,让子查询直接从索引拿数据,不用碰主表:
注意:CRM系统表别随便改,但自定义表没问题,放心加。CREATE NONCLUSTERED INDEX IX_zon_caselog_zon_case_createdon ON zon_caselog (zon_case) INCLUDE (createdon);
4. 如果非要用底层表,手动补全权限过滤
要是某些场景必须用底层表,又不想丢权限,你可以手动模拟Filtered视图的安全规则:
- 关联
systemuser、team这些表,过滤当前用户有权访问的记录 - 或者用CRM内置的
fn_GetUserPrivilegeAccess函数来做权限校验,但这种写法会复杂点,优先还是用优化后的Filtered视图查询。
5. 几个通用小技巧
- 检查下报表参数
@CreatedInLast和@ModifiedSince的取值,别一下子返回几万条数据 - 把
AgingPeriod的计算移到SSRS报表端(用表达式算),减轻数据库的负担 - 执行下
EXEC sp_updatestats更新统计信息,让SQL Server的查询优化器能生成最优的执行计划
内容的提问来源于stack exchange,提问作者Kumar Manish
相关产品推荐
相关产品推荐

