我有一个操作进行得相当缓慢,可能是因为我CROSS JOIN
首先创建了大量的行供 SQL Server 处理,这些行后来被GROUP
编辑并PIVOT
编辑成更少的行和一堆列。目的是获取每个“唯一组织名称”的“每条记录的下载次数”,其中唯一组织名称是OrganizationName
表中的唯一条目,AdamUser
下载次数是表中关联条目的数量MaintenanceJobHistory
。最后,Record
连接到每一行以输出有关该记录的更多信息。这是查询:
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]
这是执行计划:
https://www.brentozar.com/pastetheplan/?id=ry8tXM3mg
它确实给了我正确的输出,但我注意到流聚合之前的排序操作需要很长时间,并溢出到tempdb
. 这可能就是为什么查询需要大约 5 分钟的时间,我的正常数据集有 200 列,而我的测试数据集只有 6 列,PIVOT
可能只需要半分钟。就它处理的行数而言,被CROSS JOIN
编辑的两个表 (Record
和AdamUser
) 分别有 38397 行和 1017 行。
有没有办法可以加快速度,或者是否有必要为我拥有的行数和列数花费这么长时间?
我没有找到任何加速
PIVOT
操作的方法——这只是一个需要大量数据的大型操作。我做的一件事似乎稍微加快了速度(也许在 SQL Server 中更有效地实现了加法串联运算符)是更改CONCAT('Downloads_', usr.[OrganizationName])
为'Downloads_' + usr.[OrganizationName]
. 其余的似乎非常理想。