SQL - 使用连接过滤大型表 - 最佳实践

时间:2011-03-31 08:06:36

标签: sql sql-server performance

我有一个包含大量数据的表,我需要将其与其他一些大表连接。

每次我的桌子中只有一小部分与我相关。

何时最好过滤我的数据?

  1. 在SQL的where子句中。

  2. 使用特定数据创建临时表,然后加入。

  3. 将谓词添加到第一个内连接ON子句。

  4. 其他一些想法。

  5. 1

    Select * 
    From RealyBigTable
    Inner Join AnotherBigTable On …
    Inner Join YetAnotherBigTable On …
    Where RealyBigTable.Type = ?
    

    2

    Select * 
    Into #temp
    From RealyBigTable
    Where RealyBigTable.Type = ?
    
    Select * 
    From #temp
    Inner Join AnotherBigTable On …
    Inner Join YetAnotherBigTable On …
    

    3

    Select * 
    From RealyBigTable
    Inner Join AnotherBigTable On RealyBigTable.type = ? And … 
    Inner Join YetAnotherBigTable On …
    

    另一个问题: 先发生什么事? JoinWhere

3 个答案:

答案 0 :(得分:12)

因为您正在使用INNER JOIN,所以WHERE或JOIN辩论仅取决于您的品味和风格。就个人而言,我喜欢在ON子句中保留两个表之间的链接(例如外键约束),并在WHERE子句中保持对数据的实际过滤。

SQL Server会将查询解析为相同的标记树,因此将构建相同的查询执行计划。

如果你使用[LEFT / RIGHT] OUTER JOINS代替它,它会产生一个不同的世界,因为不仅性能可能不同,而且很可能是结果。

<小时/> 要回答您的其他问题:

何时最好过滤我的数据?

  1. 在SQL的where子句中。
  2. 使用特定数据创建临时表,然后才加入它。
  3. 将谓词添加到第一个内连接ON子句。
  4. 其他一些想法。
  5. 在WHERE或ON子句中,两者都被视为相同。对于3,“第一个内连接”没有相关性。在多表INNER JOIN场景中,首先(在查询中)首先无关紧要,因为查询优化器将按其认为合适的方式对顺序进行洗牌。

    使用临时表是完全没必要的,也无济于事,因为你无论如何都必须提取相关部分 - 这也是JOIN的作用。此外,如果您在JOIN条件/ WHERE过滤器上有一个很好的索引,索引将仅用于访问相关数据,而无需查看其余表格。

答案 1 :(得分:1)

您应该将您的查询放入管理工作室,勾选“包含实际执行计划”,然后运行它。这样,您将获得SQL服务器对您的查询所做的确切答案。从那时起,您可以继续优化。

一般来说:

  • 用于加入的列应编入索引
  • 首先使用最具鉴别力的过滤器

答案 2 :(得分:0)

在一个体面的基于成本的查询计划器中会发生什么(你的情况)

  1. 加入条件以及在同一级别解析条件的地方

  2. 连接类型和统计信息确定路径(首先发生的事情) - 以这种方式检索最小的中间结果(最少的I / O&gt;最快的查询)