Let me address all three performance factors you’re dealing with systematically.
Database Indexing Strategy:
First, create a composite index on your custom resource allocation table covering (ProjectId, ResourceId, StartDate, EndDate). This will eliminate the table scan you identified. Run this in a maintenance window:
CREATE NONCLUSTERED INDEX IX_ResourceAlloc_Forecast
ON CustomResourceAllocation (ProjectId, ResourceId, StartDate, EndDate)
INCLUDE (AllocationPercentage, Status);
Update statistics immediately after. For date range queries, add a filtered index for active allocations: WHERE Status = ‘Active’ AND EndDate >= GETDATE().
Query Complexity from Customizations:
Your nested loop issue is critical. Refactor the resource calculation logic to use set-based operations. Instead of looping through each resource, build a single query using CTEs or temp tables to aggregate allocation data. Move calculations that don’t change frequently to a cached table that refreshes on a schedule rather than on-demand. Implement query result caching in your X++ code using the Map class for repeated lookups within the same session.
Code Pattern for Optimization:
Replace the nested loop pattern with batch retrieval. Use QueryRun with proper ranges to fetch all required resources in one database round trip, then process them in memory. Implement lazy loading for detailed resource data - only fetch full details when users expand specific resources in the forecast view.
Additional Recommendations:
Enable query plan caching for your custom queries. Add hints like OPTION (OPTIMIZE FOR UNKNOWN) if you’re seeing parameter sniffing issues. Consider implementing a materialized view pattern where forecast aggregates are pre-calculated during off-peak hours and stored in a summary table. The forecast page then reads from this optimized table rather than calculating everything real-time.
Monitor the improvement with SQL Server DMVs - specifically sys.dm_exec_query_stats to track query duration changes. You should see load times drop to under 5 seconds for most project sizes after implementing these changes. Test with your largest projects first to validate the improvements scale properly.
This draft is based on general Microsoft Dynamics 365 knowledge. It has not been verified against your specific version and environment. Practitioners: verify the steps and share your experience below.