Eu tenho uma operação que está indo muito devagar, provavelmente porque meu CROSS JOIN
primeiro cria uma tonelada de linhas para o SQL Server trabalhar, que são posteriormente GROUP
editadas e PIVOT
transformadas em muito menos linhas e um monte de colunas. O objetivo é obter as "vezes em que cada registro foi baixado" por "nome exclusivo da organização", onde os nomes exclusivos da organização são as OrganizationName
entradas exclusivas na AdamUser
tabela e as vezes baixadas é o número de entradas associadas na MaintenanceJobHistory
tabela. Por fim, Record
é unido a cada linha para gerar mais informações sobre esse registro. Aqui está a consulta:
SELECT *
FROM (
SELECT
rec.[Id] AS RecordId,
CONCAT('Downloads_', usr.[OrganizationName]) AS OrganizationName,
COUNT(hist.[Id]) AS TimesDownloaded -- To be aggregated by PIVOT
FROM (
SELECT
innerRec.[Id]
FROM
[dbo].[Record] innerRec
INNER JOIN
[dbo].[RecordClassificationLink] innerLnk ON innerLnk.[RecordId] = innerRec.[Id]
-- WHERE (classification ID is foo or bar), for optional classification filtering
GROUP BY
innerRec.[Id]
-- HAVING COUNT(innerLnk.ClassificationId) = (number of specified classifications), for optional classification filtering
) rec
CROSS JOIN [dbo].[AdamUser] usr
LEFT JOIN (
SELECT * FROM [dbo].[MaintenanceJobHistory] WHERE [CreatedOn] > '2016-01-01 12:00:00' AND [CreatedOn] < '2016-12-01 12:00:00'
) hist ON hist.[AccessingUser] = usr.[Name] AND hist.[RecordId] = rec.[Id]
GROUP BY
rec.[Id], usr.[OrganizationName]
) srcTable
PIVOT -- Pivot around columns outside aggregation fn, eg. heading column [OrganizationName] & all other columns: [RecordId]
(
MIN(srcTable.[TimesDownloaded]) FOR [OrganizationName] IN (...~200 columns...)
) pivotTable
INNER JOIN [dbo].[Record] outerRec ON outerRec.[Id] = pivotTable.[RecordId]
E aqui está o plano de execução:
https://www.brentozar.com/pastetheplan/?id=ry8tXM3mg
Ele me fornece a saída correta, mas notei que a operação Sort antes do Stream Aggregate está demorando muito e se espalha em arquivos tempdb
. Pode ser por isso que a consulta leva ~ 5 minutos com as ~ 200 colunas que tenho para o conjunto de dados normal, enquanto meu conjunto de dados de teste com 6 colunas PIVOT
leva apenas meio minuto. Em termos de quantas linhas está lidando, as duas tabelas sendo CROSS JOIN
ed ( Record
e AdamUser
) têm 38397 e 1017 linhas, respectivamente.
Existe uma maneira de acelerar isso ou é necessário demorar tanto para o número de linhas e colunas que tenho?
Não encontrei nenhuma maneira de acelerar a
PIVOT
operação - é apenas uma grande operação que leva tempo com muitos dados. A única coisa que fiz que pareceu acelerar um pouco as coisas (talvez o operador de concatenação de adição implementado com mais eficiência no SQL Server) foi mudarCONCAT('Downloads_', usr.[OrganizationName])
para'Downloads_' + usr.[OrganizationName]
. O resto parece ser praticamente ótimo.