sql - 使用交叉应用子查询优化 sql 查询的问题
问题描述
所以我有三张桌子:
MakerParts,包含车辆零件的主要信息:
ID | 制造商 ID | 零件号 | 描述 |
---|---|---|---|
1 | 1 | ABC1234 | 胎 |
2 | 1 | XYZ1234 | 门 |
MakerPrices
,它保存了零件的价格历史变化(参考文献MakerParts.Id
和MakerPartNumberId
表格MakerPriceUpdates
)UpdateId
:
ID | 制造商零件编号 ID | 更新 ID | 价格 |
---|---|---|---|
1 | 1 | 1 | 9.83 |
2 | 1 | 2 | 11.23 |
MakerPriceUpdates
,它保存价格更新的日期。此更新基本上是上传到我们系统的 CSV 文件。一个文件,这个表一行,表上的多个价格变化MakerPrices
。
ID | 日期 | 文件名 |
---|---|---|
1 | 2019-01-09 00:00:00.000 | 临时文件 |
2 | 2019-01-11 00:00:00.000 | temp2.csv |
这意味着一个零件 (MakerParts) 可能有多个价格 (MakerPrices)。价格变化的日期在 MakerPricesUpdates 表上。
我想选择最近价格为零的所有 MakerParts,按 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 没有建议新的索引):
解决方案
尝试:
WITH tab AS (
SELECT *, NULL as Price FROM MakerParts
WHERE not exists (
SELECT Id
FROM MakerPrices
WHERE MakerPrices.MakerPartNumberId = MakerParts.Id
)
)
SELECT * from tab WHERE MakerId = 2
UNION ALL
SELECT a.* , Price
FROM [dbo].[MakerParts] a
LEFT JOIN [dbo].[MakerPrices] b
ON b.MakerPartNumberId = a.Id
WHERE MakerId = 2 AND Price = 0
推荐阅读
- wordpress - index.php 在 wordpress 本地安装中被绕过
- android - 检查Android设备是4G还是5G
- maven - jfrog rt mvn install: [错误] 地址中缺少端口
- caching - Infinispan 缓存返回空对象
- apache - 完全删除 HTTP 标头中的“Apache”?
- tensorflow - Keras(TensorFlow) 崩溃并抛出 ValueError
- wordpress - 使用 Marketplace 在 GCP 上添加了新的 WordPress 站点。发布失败。链接伪装失败
- javascript - .append 不替换相似元素
- excel - 在VBA中的字符之前获取特定字符串
- docker - Cloud Build 触发器更改文件权限并中断 docker 缓存