我有两张桌子
学生(Id,DatasetId和其他专栏)
和
StudentAddress(Id,StudentId,DatasetId,Country和其他列)。
StudentAddress有2个外键 StudentID 引用学生 - Id **和 DatasetId **引用学生 - 数据集。两个表都有5000万条记录,一对一关系具有不同的DatasetId值。
--This query took 01:20 minutes
Select * from Student S
LEFT JOIN StudentAddress SA on S.Id = SA.StudentId
WHERE S.DatasetId = SA.DatasetId AND S.DatasetId = 123
--This query took 01:18 minutes
Select * from Student S
LEFT JOIN StudentAddress SA on S.Id = SA.StudentId
WHERE S.DatasetId = 123 AND SA.DatasetId = 123
--This query took 01:19 minutes
Select * from Student S
LEFT JOIN StudentAddress SA on S.Id = SA.StudentId
WHERE S.DatasetId = SA.DatasetId AND S.DatasetId = 123 AND SA.DatasetId = 123
1)上述3个查询之间的性能是否存在差异?当我在我的数据库中执行这些查询时,所有查询都会产生相同的性能。我不是解释实际查询执行计划的专家。因此,请专家了解哪个查询会带来更好的效果。
2)如果我改变第一个查询的WHERE子句中的条件顺序,性能是否会有任何差异?
3)另外,我的理解是两个表中的数据将在DatasetId上过滤,然后LEFT JOIN将应用于过滤后的数据。我的理解是否正确?
答案 0 :(得分:0)
仍然......查询1和2在逻辑上是不同的。第二个查询将从SA中排除任何不匹配的NULL行。
同样,这个问题并没有多大意义,因为你正在使用和OUTER JOIN然后你去过外表上过滤
所以..
1)查询2& 3可能是一样的。查询1在逻辑上是不同的。如果它们都是内部连接,我希望它们都是相同的
2)WHERE子句中的谓词顺序对性能没有影响
3)否。要在应用外部联接之前进行预过滤,您需要将其包含在ON
子句中
例如,这些是非常不同的:
在此查询中,SA的记录可能为NULL。
S.DatasetId = 123
不会排除他们
Select * from Student S
LEFT JOIN StudentAddress SA on S.Id = SA.StudentId
WHERE S.DatasetId = SA.DatasetId
AND S.DatasetId = 123
在此查询中,SA的记录可能为NULL。
因此,S.DatasetId = 123
将排除它们。
Select * from Student S
LEFT JOIN StudentAddress SA on S.Id = SA.StudentId
WHERE S.DatasetId = 123 AND SA.DatasetId = 123
此查询再次执行某些操作:
Select * from Student S
LEFT JOIN StudentAddress SA
ON S.Id = SA.StudentId
AND SA.DatasetId = 123
WHERE S.DatasetId = 123
关于问题1& 2,你可以生成查询计划并注意它们都是一样的(你不必理解它,只需注意它就是一样)
最后,数据库服务器的配置不同,因此查询计划总是可能不同但很可能不是
在这种情况下,为什么使用LEFT OUTER JOIN?