SQL 加入和过滤

SQL join and filtering

这两个解决方案是否给出相同的结果?

SELECT *
FROM Orders
LEFT JOIN OrderLines ON OrderLines.OrderID=Orders.ID 
    AND Orders.ID = 12345

select orderID
into #temp
from OrderLines
where orderID=12345

SELECT *
    FROM Orders
    LEFT JOIN #temp t ON t.OrderID=Orders.ID 
        

我想使用临时表来提高性能

I would like to use the temp tables for performance

我的基本反应是:算了吧。临时 table 在某些情况下很有用,特别是当脚本是 运行 多个查询并且需要共享某个子查询时。但是,它们在创建 table、用数据加载它然后再次读取它时会产生开销。这可能会带来很多开销。

不过,总的来说,在开发数据库及其优化器方面付出了很多努力。您通常可以相信优化器会做正确的事情。无需尝试智取优化器。

有时候,优化器并不完美。大多数数据库支持使用一些提示来生成更 suitable 的查询计划。在某些情况下,您可能会发现使用适当的索引创建临时 table 会产生更好的查询计划。

在大多数情况下,您的第一个查询会比第二个查询快。如果不是,则 OrderLines 上的统计数据可能已过时。

SELECT *
FROM Orders
LEFT JOIN OrderLines ON OrderLines.OrderID=Orders.ID 
    AND Orders.ID = 12345

这个查询会给你

  • 来自 Orders table
  • 的所有记录
  • 来自 OrderLines table 的匹配记录仅针对具有 ID = 12345 的所有其他订单,您会发现 OrderLines Null。

--

select orderID
into #temp
from OrderLines
where orderID=12345

SELECT *
    FROM Orders
    LEFT JOIN #temp t ON t.OrderID=Orders.ID

让我们考虑您的第一个查询,您仅从 OrderLines 中获取那些记录,其中 OrderId = 12345 然后将其与 Orders table 连接。所以你的查询输出将是

  • 来自 Orders table
  • 的所有记录
  • 对于 OrderID 12345,OrderLines 将可用,对于所有其他,Orderlines 将为空

所以是的,两个查询都会给你相同的输出