我有一个查询,我正在尽力优化,如果我可以使用连接而不是当前的连接(一个WHERE IN),它会帮助我很多。
目前,我的查询是:
SELECT
cus.*
, com.COM_ID
, cha.CHA_NAME
FROM thing.dbo.VIEW_REPORT cus --View
LEFT JOIN otherthing.dbo.TBL_COMMUNICATION com
ON com.REC_ID = cus.REC_ID
AND com.RUN_ID = cus.RUN_ID
LEFT JOIN otherthing.dbo.TBL_CHANNEL cha
ON cha.CHA_ID = com.CHA_ID
WHERE com.COM_ID in (
SELECT eve.COM_ID
FROM otherthing.dbo.TBL_EVENT eve)
我正在尝试通过加入TBL_EVENT而不是WHERE IN来优化它(我相信我读它们的运行方式相同,但我也想选择一些TBL_EVENT列,所以加入会很好) 。我的新查询是这样的:
SELECT
cus.*
, com.COM_ID
, cha.CHA_NAME
FROM thing.dbo.VIEW_REPORT cus --View
LEFT JOIN otherthing.dbo.TBL_COMMUNICATION com
ON com.REC_ID = cus.REC_ID
AND com.RUN_ID = cus.RUN_ID
LEFT JOIN otherthing.dbo.TBL_CHANNEL cha
ON cha.CHA_ID = com.CHA_ID
INNER JOIN otherthing.dbo.TBL_EVENT eve
ON com.COM_ID = eve.COM_ID
我认为使用内部联接意味着它只返回TBL_COMMUNICATION和TBL_EVENT中的结果。 这就是事情变得怪异的地方。
原始查询(在顶部)返回~200,000条记录。我的新查询返回约1,100,000条记录。但从我的角度来看,他们是同一个查询,所以我不确定我做错了什么。我已将INNER JOIN移动到其他左连接之上的TBL_EVENT,但它似乎没有什么区别。
任何人都可以通过加入TBL_EVENT来告诉我应该做些什么来返回相同的数据?
答案 0 :(得分:2)
他们不一样
WHERE com.COM_ID in (
SELECT eve.COM_ID
FROM otherthing.dbo.TBL_EVENT eve)
说必须在子查询的结果中找到com.COM_ID。但
INNER JOIN otherthing.dbo.TBL_EVENT eve
ON com.COM_ID = eve.COM_ID
表示要加入eve.COM_ID与com.COM_ID相同的所有帖子。
如果您在eve.COM_ID中有多个具有相同COM_ID的帖子,您的结果中会有多个帖子。
答案 1 :(得分:0)
这里没有什么是奇怪的,当TBL_EVENT中有超过1行与VIEW_REPORT和TBL_COMMUNICATION的1行连接匹配时会发生这种情况。
您不能像第二个脚本那样优化以获得相同的结果
您可以像下面那样优化sql,而不是重用第一个,这样可以提高脚本的速度
SELECT
cus.*
, com.COM_ID
, cha.CHA_NAME
FROM thing.dbo.VIEW_REPORT cus --View
LEFT JOIN otherthing.dbo.TBL_COMMUNICATION com
ON com.REC_ID = cus.REC_ID
AND com.RUN_ID = cus.RUN_ID
and com.COM_ID in (
SELECT distinct eve.COM_ID
FROM otherthing.dbo.TBL_EVENT eve)
LEFT JOIN otherthing.dbo.TBL_CHANNEL cha
ON cha.CHA_ID = com.CHA_ID
INNER JOIN otherthing.dbo.TBL_EVENT eve
ON com.COM_ID = eve.COM_ID
或
SELECT
cus.*
, com.COM_ID
, cha.CHA_NAME
FROM thing.dbo.VIEW_REPORT cus --View
LEFT JOIN (SELECT * FROM otherthing.dbo.TBL_COMMUNICATION com WHERE com.COM_ID IN (SELECT distinct eve.COM_ID FROM otherthing.dbo.TBL_EVENT eve)) com
ON com.REC_ID = cus.REC_ID
AND com.RUN_ID = cus.RUN_ID
LEFT JOIN otherthing.dbo.TBL_CHANNEL cha
ON cha.CHA_ID = com.CHA_ID
答案 2 :(得分:0)
你杀了LEFT JOIN otherthing.dbo.TBL_COMMUNICATION com与where,所以这会给你另一个答案。如果您更喜欢第一个答案,请将其更改为常规联接。
SELECT cus.*, com.COM_ID, cha.CHA_NAME
FROM thing.dbo.VIEW_REPORT cus --View
LEFT JOIN otherthing.dbo.TBL_COMMUNICATION com
ON com.REC_ID = cus.REC_ID
AND com.RUN_ID = cus.RUN_ID
AND exists ( SELECT 1
FROM otherthing.dbo.TBL_EVENT eve
where eve.COM_ID = com.COM_ID )
LEFT JOIN otherthing.dbo.TBL_CHANNEL cha
ON cha.CHA_ID = com.CHA_ID
但是这个问题对我来说没有意义
为什么要限制左连接的右侧?
很确定你的意思是内部联接。
SELECT cus.*, com.COM_ID, cha.CHA_NAME
FROM thing.dbo.VIEW_REPORT cus --View
JOIN otherthing.dbo.TBL_COMMUNICATION com
ON com.REC_ID = cus.REC_ID
AND com.RUN_ID = cus.RUN_ID
AND exists ( SELECT 1
FROM otherthing.dbo.TBL_EVENT eve
where eve.COM_ID = com.COM_ID )
LEFT JOIN otherthing.dbo.TBL_CHANNEL cha
ON cha.CHA_ID = com.CHA_ID
发布查询计划