Good day.
Below is the text of the query, it gives the correct results, but it takes too long. Please help optimize it (this is my latest and current version of the query.):
DECLARE @dateFrom datetime = @filter.value('(FilterSet/items[@name="dateFrom"])[1]', 'datetime'); DECLARE @dateTo datetime = @filter.value('(FilterSet/items[@name="dateTo"])[1]', 'datetime'); DECLARE @costTable table (providerName varchar(50), clientName varchar(50),messageId int, [count] int, cost numeric(18,3), [month] date ) INSERT @costTable SELECT p.providerName, c.clientName, m.messageId, [dbo].[func_GetSmsCount] (m.messageId, m.[recipient], p.providerId, m.dt, ms.statusValue), [dbo].[func_GetSmsCost] (m.messageId, m.[recipient], p.providerId, m.dt, ms.statusValue), DATEADD(MONTH, DATEDIFF(MONTH, 0, m.[dt]), 0) as DT FROM [dbo].[Messages] (NOLOCK) m INNER JOIN [dbo].[MessageStatus] (NOLOCK) ms ON m.messageId = ms.messageId INNER JOIN [dbo].[Clients] (NOLOCK) c ON m.clientId = c.clientId INNER JOIN [dbo].[Debtors] (NOLOCK) d ON c.debtorId = d.debtorId INNER JOIN [dbo].[Providers] (NOLOCK) p ON ms.providerId = p.providerId WHERE ms.statusId = 2 AND p.isEmail != 1 AND CAST(m.dt as date) >= @dateFrom AND CAST(m.dt as date) <= @dateTo AND ((ms.[providerId] = 6) OR (ms.[providerId] = 2) OR (ms.[providerId] = 1) ) GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, m.[dt]), 0), p.providerName, c.clientName, m.messageId, m.[recipient], p.providerId, m.dt, [dbo].[func_GetSmsCount] (m.messageId, m.[recipient], p.providerId, m.dt, ms.statusValue), [dbo].[func_GetSmsCost] (m.messageId, m.[recipient], p.providerId, m.dt, ms.statusValue) SELECT [month], providerName, SUM(cost) as [summ], COUNT(cost) as [smsCount], COUNT(1) [TotalCount], COUNT(1) - COUNT(cost) as [ErrorCount], SUM([count]) as partCount FROM @costTable GROUP BY [month], providerName ORDER BY [month] desc, providerName Thank.

func_GetSmsCountandfunc_GetSmsCost. It may be possible to combine these two scalar functions into one inline-table. Also, if there are no records inProvidersandClientswith the same names, but differentId, then it is better to group them by theirId, rather than by name, and attach theProvidersandClientsto the already grouped data. Then, perhaps, look at the missing indexes. - i-one