我试图优化下面的SQL查询,但我在select子句中遇到了子查询。
select F.id,
(select top 1 RF1.gid from t_RemFinding RF1 where RF1.id = RF.id and RF1.active = 1) as GI
from t_Finding F
left join t_RemFinding RF on RF.id = F.id
where F.Gid = '1001'
有人可以解释一下select子句中的select子查询是如何工作的。我想,子查询在外部查询的每次迭代中运行。是对的吗?我能优化吗?如果是这样,你能指导我吗?谢谢
修改
如果tb_RemFinding已经在左连接中使用,为什么在select子查询中使用相同的表并匹配相同的表。任何帮助是极大的赞赏。该查询是由其他开发人员编写的,我正在尝试重写它。
答案 0 :(得分:1)
在每次迭代中,您的子查询都会再次运行。您现在可以做的最好的事情是通过字段id,active
对t_RemFinding进行多重索引虽然没有指定和顺序的TOP 1没有多大意义(它可以采取任何满足其条件的记录)。
最好应该是这样的:
select F.id,
(select top 1 RF1.gid from t_RemFinding RF1 where RF1.id = RF.id and RF1.active = 1 order by RF1.gid desc) as GI
from t_Finding F
left join t_RemFinding RF on RF.id = F.id
where F.Gid = '1001'
现在你可以通过id,active,gid上的t_RemFinding上的多索引来更好地优化它
答案 1 :(得分:1)
我假设你不想在外部查询中使用join
:
select F.id,
(select top 1 RF1.gid
from t_RemFinding RF1
where RF1.id = F.id and RF1.active = 1
) as GI
from t_Finding F
where F.Gid = 1001 ; -- removed the single quotes
假设F.Gid
是一个数字,请不要在常量周围使用单引号。
然后,您需要两个索引:t_Finding(Gid, id)
和t_RemFinding(id, active, gid)
。
我还注意到ORDER BY
条款缺少TOP
。这通常表明存在问题。但有时候,您只需要任意任意值,因此它取决于查询的意图。
答案 2 :(得分:0)
使用 PartitionBy :
select
X.id,
X.gid as GI
from
(
select
F.id,
RF.gid as GI,
ROW_NUMBER() OVER(Partition BY RF.id ORDER BY RF.gid) AS PartNo
from t_Finding F
left join t_RemFinding RF on RF.id = F.id
AND RF.active = 1
where F.Gid = '1001'
)X
where X.PartNo=1
答案 3 :(得分:0)
您可以使用外部应用运算符。
SELECT F.id,t.gid
FROM t_Finding a
OUTER APPLY (select top 1 b.gid from t_RemFinding b where b.id = a.id and b.active = 1)t
WHERE F.Gid = '1001'
答案 4 :(得分:0)
您也可以使用OUTER APPLY,如果只想从整个查询中激活,您可以在where子句中检查活动状态。
SELECT RF.id, GI.gid
FROM t_Finding RF
OUTER APPLY (SELECT TOP 1 RF1.gid
FROM t_RemFinding RF1
WHERE RF1.id = RF.id AND RF1.active = 1
ORDER BY RF1.id DESC) AS GI
WHERE RF.Gid = '1001'
答案 5 :(得分:0)
如果没有表的一些示例数据以及输出应该是什么样子,很难回答这个问题。查看查询时,查询似乎会尝试返回“gid”ID,但仅针对仍处于活动状态的记录RF1.Active = 1
。如果这是正确的,那么一个简单的case语句应该可以胜任。
SELECT F.id,
(
CASE
WHEN RF.active = 1 THEN RF.gid
ELSE NULL
END
) AS GI
FROM t_Finding F
LEFT JOIN t_RemFinding RF on RF.id = F.id
WHERE F.Gid = '1001'