如何解决在 SQL 中生成每日总和的最有效方法?
我正在开发一个包含多个组件的管理系统,其中一个是物理部件的管理。
在 SQL 中,我有一个零件转移表,说明他们要去哪里,他们来自哪里,以及转移发生的日期。与此相关的是每个转移的表格,其中包含转移的每个部分的条目以及金额。这些部分被连接到一个单独的表中,表明它们的类型。
我正在尝试构建一个报告,显示:自第一次零件转移以来的每一天,当天每个位置当前每种零件类型的数量是多少。我有一些 SQL 可以在我们较新的站点上很好地运行,但对于我们运行时间较长的站点(2017 年),由于零件/位置/天数如此之多,因此需要很长时间。
试图优化它以使其在大量数据上运行是愚蠢的差事吗?我正在寻找推进此工作的最佳方式,无论是开始构建某种记录缓存,还是在最有效的计算方式方面我遗漏了什么。
作为参考,以下是从我们最大的网站中提取的一些数据:
数据 | 计数 |
---|---|
地点 | 20496 |
零件类型 | 224 |
天 | 1176 |
这里是大部分相关的 SQL,为了清楚起见,我确实清除了一些部分,但如果有遗漏,请告诉我,我会重新添加。
SELECT @earliestTransaction = min(actual_date) from partlist
WHERE (partlist.item_type = 'scaffold'
AND partlist.partlist_type_id = 15)
OR partlist.partlist_type_id = 6
SELECT @today = (select cast(getdate() as Date))
INSERT INTO @relevantScaffolds
SELECT s.id
from scaffold s
join sitearea wa on wa.id = s.sitearea_id
where s.project_id = @ProjectID
AND (
(@siteAreaID IS NULL AND @scaffoldID IS NULL)
OR (@siteAreaID IS NOT NULL AND wa.parent_sitearea_id = @siteAreaID)
OR (@scaffoldID IS NOT NULL AND s.id = @scaffoldID)
)
WITH DateTable AS
(
SELECT @earliestTransaction AS [DATE]
UNION ALL
SELECT DATEADD(dd,1,[DATE])
FROM DateTable
WHERE DATEADD(dd,[DATE]) <= @today
)
--Get Date collection for all parts
INSERT INTO @datesAndParts
select DISTINCT
dt.DATE,pc.id,rs.scaffold_id
from DateTable dt
join part_catalog pc on 1=1
join @relevantScaffolds rs on 1=1
--Remove limit for date recurison
OPTION (MaxRecursion 0)
WITH scaffold_transactions(part_catalog_id,quantity,actual_date,project_id,scaffold_id) AS
(
-- Into Scaffold
SELECT part_catalog_id,sum(quantity),partlist.actual_date,partlist.project_id,rs.scaffold_id
FROM partlist
INNER JOIN partlist_part on partlist_part.partlist_id = partlist.id
left join partlist parent on parent.id = partlist.parent_partlist_id
join part_catalog on part_catalog.id = partlist_part.part_catalog_id
join @relevantScaffolds rs on rs.scaffold_id = partlist.item_id
WHERE partlist.item_type = 'scaffold'
AND partlist.partlist_type_id = 15
AND partlist.project_id = @ProjectID
GROUP BY part_catalog_id,rs.scaffold_id
UNION ALL
-- deliveries_to_scaffold
SELECT part_catalog_id,SUM(quantity),rs.scaffold_id
FROM partlist
INNER JOIN workorder on workorder.id = partlist.item_id
join @relevantScaffolds rs on rs.scaffold_id = workorder.scaffold_id
INNER JOIN partlist_part on partlist_part.partlist_id = partlist.id
left join partlist parent on parent.id = partlist.partsource_partlist_id
join part_catalog on part_catalog.id = partlist_part.part_catalog_id
WHERE partlist.partlist_type_id = 6
AND partlist.project_id = @ProjectID
GROUP BY part_catalog_id,rs.scaffold_id
UNION ALL
-- leaving_scaffold (negated quantities)
SELECT part_catalog_id,-SUM(quantity),transferPartlist.actual_date,transferPartlist.project_id,rs.scaffold_id
FROM partlist transferPartlist
INNER JOIN partlist scaffoldPartlist on scaffoldPartlist.id = transferPartlist.parent_partlist_id
INNER JOIN partlist_part on partlist_part.partlist_id = transferPartlist.id
join part_catalog on part_catalog.id = partlist_part.part_catalog_id
join @relevantScaffolds rs on rs.scaffold_id = scaffoldPartlist.item_id
WHERE transferPartlist.partlist_type_id = 15
AND scaffoldpartlist.partlist_type_id = 9
AND scaffoldpartlist.project_id = @ProjectID
GROUP BY part_catalog_id,rs.scaffold_id
)
INSERT INTO @keyedTransfers
select part_catalog_id,scaffold_id from scaffold_transactions
group by part_catalog_id,scaffold_id
INSERT INTO @cleanupTable
select
dap.date as date,dap.part_catalog_id,dap.scaffold_id,COALESCE(SUM(quantity) over (partition by dap.part_catalog_id,dap.scaffold_id order by dap.date ),0) as balance
from @datesAndParts dap
left join @keyedTransfers kt on kt.actual_date = dap.date and kt.part_catalog_id = dap.part_catalog_id and kt.scaffold_id = dap.scaffold_id
select date,pc.part_number,pc.description,scaffold.tag,balance
from @cleanupTable ct
join part_catalog pc on pc.id = ct.part_catalog_id
join scaffold on scaffold.id = ct.scaffold_id
where date >= @earliestTransaction AND date <= @today
and balance > 0
order by date,part_number
Here's a link to the execution plan 在成功的网站之一上运行时。我们在不同站点之间存在差距,它们都非常小或很大,中间没有,所以这个数据集要小得多。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。