SQL - 使用连接过滤大表 - 最佳实践
Posted
技术标签:
【中文标题】SQL - 使用连接过滤大表 - 最佳实践【英文标题】:SQL - Filtering large tables with joins - best practices 【发布时间】:2011-03-31 08:06:35 【问题描述】:我有一个包含大量数据的表,我需要将它与其他一些大表连接起来。
每次我的表中只有一小部分与我真正相关。
什么时候最好过滤我的数据?
在 SQL 的 where 子句中。
使用特定数据创建一个临时表,然后才加入它。
将谓词添加到第一个内连接 ON 子句。
其他想法。
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 …
另一个问题:
首先会发生什么? Join
或 Where
?
【问题讨论】:
【参考方案1】:因为您使用的是 INNER JOIN,所以 WHERE 或 JOIN 的争论只取决于您的品味和风格。就个人而言,我喜欢在 ON 子句中保留两个表之间的链接(例如外键约束),并在 WHERE 子句中对数据进行实际过滤。
SQL Server 会将查询解析为相同的标记树,因此会构建相同的查询执行计划。
如果您改用 [LEFT/RIGHT] OUTER JOINS,它会产生很大的不同,因为不仅性能可能不同,而且结果也很可能不同。
要回答您的其他问题:
什么时候最好过滤我的数据?
-
在 SQL 的 where 子句中。
使用特定数据创建一个临时表,然后才加入它。
将谓词添加到第一个内连接 ON 子句。
其他一些想法。
在 WHERE 或 ON 子句中,两者被视为相同。对于 3,“first 内连接”没有相关性。在多表 INNER JOIN 场景中,哪个先执行(在查询中)实际上并不重要,因为查询优化器会根据需要调整顺序。
使用临时表是完全没有必要的,也无济于事,因为无论如何您都必须提取相关部分——这也是 JOIN 会做的事情。此外,如果您在 JOIN 条件/WHERE 过滤器上有一个良好的索引,则该索引将仅用于访问相关数据,而无需查看表的其余部分。
【讨论】:
好的。但是将数据放在临时表中然后才(内部)加入不同的表不是更好吗?【参考方案2】:您应该将您的查询放在管理工作室中,勾选“包括实际执行计划”,然后运行它。这样,您将获得 SQL Server 对您的查询所做的确切答案。从那时起,您可以继续优化。
一般:
用于连接的列应该被索引 首先使用最具辨别力的过滤器【讨论】:
【参考方案3】:在一个体面的基于成本的查询计划器中会发生什么(你的情况)
join 条件和 where 条件在同一级别解析
连接类型和统计信息确定路径(先发生什么) - 以这样一种方式检索最小的中间结果(最少 I/O > 最快查询)
【讨论】:
以上是关于SQL - 使用连接过滤大表 - 最佳实践的主要内容,如果未能解决你的问题,请参考以下文章