【问题标题】:SQL - Filtering large tables with joins - best practicesSQL - 使用连接过滤大表 - 最佳实践
【发布时间】:2011-03-31 08:06:35
【问题描述】:

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

每次我的表中只有一小部分与我真正相关。

什么时候最好过滤我的数据?

  1. 在 SQL 的 where 子句中。

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

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

  4. 其他想法。

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?

【问题讨论】:

    标签: sql sql-server performance


    【解决方案1】:

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

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

    如果您改用 [LEFT/RIGHT] OUTER JOINS,它会产生很大的不同,因为不仅性能可能不同,而且结果也很可能不同。


    要回答您的其他问题:

    什么时候最好过滤我的数据?

    1. 在 SQL 的 where 子句中。
    2. 使用特定数据创建一个临时表,然后才加入它。
    3. 将谓词添加到第一个内连接 ON 子句。
    4. 其他一些想法。

    在 WHERE 或 ON 子句中,两者被视为相同。对于 3,“first 内连接”没有相关性。在多表 INNER JOIN 场景中,哪个先执行(在查询中)实际上并不重要,因为查询优化器会根据需要调整顺序。

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

    【讨论】:

    • 好的。但是将数据放在临时表中然后才(内部)加入不同的表不是更好吗?
    【解决方案2】:

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

    一般:

    • 用于连接的列应该被索引
    • 首先使用最具辨别力的过滤器

    【讨论】:

      【解决方案3】:

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

      1. join 条件和 where 条件在同一级别解析

      2. 连接类型和统计信息确定路径(先发生什么) - 以这样一种方式检索最小的中间结果(最少 I/O > 最快查询)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-17
        • 2011-03-19
        • 1970-01-01
        • 2021-06-25
        • 2017-09-07
        • 2015-03-25
        • 2017-12-13
        • 2014-05-23
        相关资源
        最近更新 更多