我正在阅读一本书"内部Microsoft SQL Server 2008:T-SQL查询*这是一个例子,在两个表之间进行任何连接时,首先笛卡尔积在它们之间发生然后它被过滤了ON条件然后由" RIGHT"," LEFT"或" FULL"加入类型。
来自该书的一个例子,
SELECT C.customerid, COUNT(O.orderid) AS numorders
FROM dbo.Customers AS C
LEFT OUTER JOIN dbo.Orders AS O
ON C.customerid = O.customerid
客户表有4行,订单有7行。因此,第一个笛卡尔积将生成4 * 7 = 28行,然后它将通过" ON"条款和LEFT OUTER。
这是否意味着无论我使用的连接类型如何,每次笛卡尔产品都会在表之间发生?那么为什么我们看到不同连接之间的性能差异呢?
答案 0 :(得分:5)
SQL Server当然不会为每个连接计算笛卡尔积,然后对其进行过滤,它所做的就是将你的SQL语句用左,右,内......你指定的任何连接类型,然后是优化器将根据表中存在的关于要使用的物理连接运算符的统计信息做出决定。
有3个物理操作符:
所有3个都有自己最理想的场景(我不打算在这里解释,每个都有很多文章),而且主要取决于每个表格的基数估计值。有关优化程序期望返回的行数的连接和统计信息。
Craig Freedman有一系列博客文章讨论了如何在SQL服务器中使用联接:
我建议查看该列表中的最后5篇文章,其中包括对联接的介绍,联接属性的摘要,然后合理地深入了解每个物理联接运算符。
答案 1 :(得分:1)
两个表之间的任何连接首先在它们之间发生笛卡尔积,然后用ON条件过滤,然后用“RIGHT”,“LEFT”或“FULL”连接类型过滤。
只是对所做事情的逻辑描述。结果将与此相同,但它将根据您拥有的索引和表中的数据进行不同的实现。
请参阅set showplan on
,然后进行查询,它将解释如何查找数据。希望这本书能够解释这一点,因为你进一步了解它。
答案 2 :(得分:1)
说笛卡尔积发生了然后被过滤是非常误导的。如果是这种情况,那么加入200万行表几乎是不可能的,因为首先,你将从一万亿行结果集开始然后过滤它。没有多少SQL-Server实现可以处理那个。
所以,不,对于编写良好的查询,笛卡尔积不是该过程的第一步。对于写得不好的查询,所有投注均已关闭。可以强制SQL-Server做出这个选择,但这几乎无疑是程序员错误的一个简单例子。