等效查询,不同结果和执行时间

时间:2016-04-07 19:14:08

标签: sql-server tsql join

编辑:查询计划链接到:

Bad Query

Good Query

所以我正在研究MSSQL系统,我正在重写一些查询。我决定使用我的谓词,主要是通过从WHERE子句移动它们,并将它们填充到我的JOIN子句中。当我这样做时,它返回了两倍的行,执行时间从几秒钟到几分钟。

我想知道发生了什么,因为我认为查询分析器经常会将谓词填充到JOIN子句中,因为这些行最终会被丢弃。

任何关于为什么这些查询都不相同的帮助将非常感激,我只是不够强大,知道在哪里看......

好查询:

FROM [CONNECT_PROD].[dbo].[CRM_C005] c005 
LEFT JOIN [CONNECT_PROD].[dbo].[CRM_FI] fi ON c005.ID_FI = fi.ID
LEFT JOIN [CONNECT_PROD].[dbo].[CRM_CPPE] kp ON c005.ID_PE = kp.ID_PE AND  fi.id = kp.id_fi
LEFT JOIN [CONNECT_PROD].[dbo].[CRM_KA] vko ON c005.F7010 = vko.code 
LEFT JOIN [CONNECT_PROD].[dbo].[CRM_VF] vf on vf.id_fi = fi.id and vf.VerkOrg = vko.code
LEFT JOIN [CONNECT_PROD].[dbo].[CRM_KA] land ON fi.land = land.code 
LEFT JOIN [CONNECT_PROD].[dbo].[CRM_KA] title ON kp.Titel = title.code and title.loskz = 0 and title.KatSperre = 0 and title.sprachenr = 0 and title.katnr = 23
WHERE kp.loskz = 0
and vko.loskz = 0
and vko.KatSperre = 0
and vko.sprachenr = 0
and vko.katnr = 274
and vko.ExtKey = '0014'
and land.loskz = 0
and land.KatSperre = 0
and land.sprachenr = 1000
and land.katnr = 2
and fi.loskz = 0
and fi.F7029 = 0
and vf.loskz = 0
and vf.F7023 = 0
and vf.F7152 = 0
and c005.del = 0
and kp.f7017 = 0

错误查询:

FROM [CONNECT_PROD].[dbo].[CRM_C005] c005 
LEFT JOIN [CONNECT_PROD].[dbo].[CRM_FI] fi ON c005.ID_FI = fi.ID AND fi.loskz = 0 AND fi.F7029 = 0
LEFT JOIN [CONNECT_PROD].[dbo].[CRM_CPPE] kp ON c005.ID_PE = kp.ID_PE AND fi.id = kp.id_fi AND kp.loskz = 0 AND kp.f7017 = 0
LEFT JOIN [CONNECT_PROD].[dbo].[CRM_KA] vko ON c005.F7010 = vko.code AND vko.loskz = 0 AND vko.KatSperre = 0 AND vko.sprachenr = 0 AND vko.katnr = 274 and vko.ExtKey = '0014'
LEFT JOIN [CONNECT_PROD].[dbo].[CRM_VF] vf on vf.id_fi = fi.id and vf.VerkOrg = vko.code AND vf.loskz = 0 AND vf.F7023 = 0 AND vf.F7152 = 0
LEFT JOIN [CONNECT_PROD].[dbo].[CRM_KA] land ON fi.land = land.code AND land.loskz = 0 AND land.KatSperre = 0 AND land.sprachenr = 1000 AND land.katnr = 2
LEFT JOIN [CONNECT_PROD].[dbo].[CRM_KA] title ON kp.Titel = title.code and title.loskz = 0 and title.KatSperre = 0 and title.sprachenr = 0 and title.katnr = 23
WHERE c005.del = 0

1 个答案:

答案 0 :(得分:2)

假设这个例子:我有一个包含100,000个电话的表。有某些类型的电话:入站和出站。当我写一个

的查询时
SELECT * 
FROM calls c
LEFT JOIN calltypes ct
ON c.calltypeID = ct.calltypeID
WHERE c.calltypeID = 1 --Assume this is inbound

此查询将仅返回来自我的调用表的入站调用。

现在,如果我写:

SELECT * 
    FROM calls c
    LEFT JOIN calltypes ct
    ON c.calltypeID = ct.calltypeID
    AND c.calltypeID = 1 

我将返回100,000行。左连接无法找到合适的连接条件,因此它为ct表的值返回空值。这是一个示例,说明当您在连接条件中使用where子句时,查询可能会返回更多行。