所以我有三个表:
MakerParts,保存车辆零件的主要信息:
MakerPrices
,它保存零件的价格历史变化(MakerParts.Id
上的引用 MakerPartNumberId
,以及 MakerPriceUpdates
上的表 UpdateId
):
MakerPriceUpdates
,保存价格更新的日期。此更新基本上是上传到我们系统的 CSV 文件。一个文件,这个表一行,表上多个价格变动MakerPrices
.
这意味着一个零件 (MakerParts) 可能有多个价格 (MakerPrices)。价格更改的日期位于 MakerPricesUpdates 表中。
我想要选择最新价格为零的所有 MakerPart,并按表 MakerParts 上的 MakerId 进行过滤。
我尝试过的:
select mp.* from MakerParts mp cross apply
(select top 1 Price from MakerPrices inner join
MakerPricesUpdates on MakerPricesUpdates.Id = MakerPrices.UpdateId where
MakerPrices.MakerPartNumberId = mp.Id order by Date desc) as p
where mp.MakerId = 1 and p.Price = 0
但这速度慢得离谱(MakerPrices 表上有大约 1 亿行)。我很难优化这个查询。 (结果只有两行 MakerId 1,并且运行了 2 分钟)。我也尝试过:
select * from (
select
mp.*,
(select top 1 Price from MakerPrices inner join
MakerPricesUpdates on MakerPricesUpdates.Id = MakerPrices.UpdateId
where MakerPrices.MakerPartNumberId = mp.Id order by Date desc) as Price
from MakerParts mp) as temp
where temp.Price = 0 and MakerId = 1
相同的结果,相同的时间。我的查询计划(第一个查询)(Management Studio 没有建议新索引):
最佳答案
我认为您可以避免将 MakerPriceUpdates
与 makerprices
一起加入,因为具有最高的
UpdateId
您可以找到最新的价格更新。这会节省您一些时间。
select mp.* from MakerParts mp cross apply
(select top 1 Price from MakerPrices where
MakerPrices.MakerPartNumberId = mp.Id order by MakerPrices.UpdateId desc) as p
where mp.MakerId = 1 and p.Price = 0
您可以通过避免使用 cte 和 row_number() 进行排序和排序来进一步减少一些时间,如下所示:
;with LatestMakerPrices as
(
select *,row_number()over(partition by MakerPartNumberId order by updateid desc)rn from MakerPrices
)
select mp.* from MakerParts mp cross apply
(select price from LatestMakerPrices lmp where lmp.MakerPartNumberId=mp.Id) as p
where mp.MakerId = 1 and p.Price = 0
关于sql - 使用交叉应用子查询优化sql查询时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66882021/