【问题标题】:How to optimize join of multiple (large) tables如何优化多个(大)表的连接
【发布时间】:2021-08-18 14:39:13
【问题描述】:

我正在尝试在 SQL Server 中使用 LEFT OUTER 连接多个表。在下面的示例中,左边的表并没有那么大,但右边的表大约有 4-5 百万行,而这只是两个表。还有 3 个表需要加入,它们是相当大的表。

-- Example of join for 2 tables
SELECT a.id, a.user_name, a.start_timestamp, a.ref1, a.ref2, a.ref3. a.ref4, b.start_timestamp, b.ref1, b.ref2, b.ref3. b.ref4
FROM
(
  SELECT id, user_name, start_timestamp, ref1, ref2, ref3. ref4
  FROM user
  WHERE DATEDIFF(day,[start_timestamp],GETDATE()) between 0 and 7 
) a
LEFT JOIN
(
  SELECT id, user_name, start_timestamp, ref1, ref2, ref3. ref4
  FROM user_activity
  WHERE DATEDIFF(day,[start_timestamp],GETDATE()) between 0 and 7 

) b
ON a.id = b.id

我试图将列限制在绝对必要的字段中,并且只占用最近 7 天的时间,但是 SQL 查询非常慢并且需要很长时间。有没有办法优化连接?

【问题讨论】:

  • 不要让你的服务器做代数,它不擅长:WHERE DATEDIFF(day,[start_timestamp],GETDATE()) between 0 and 7 应该是WHERE start_timestamp >= DATEADD(day, -7, GETDATE()) AND start_timestamp < GETDATE()。您可能还需要在 start_timestamp 上使用 INCLUDE 列的索引。请注意,您所做的子查询对性能没有影响。如需更好的建议,请edit 添加您的表和索引定义,并通过brentozar.com/pastetheplan分享查询计划

标签: sql sql-server left-join query-optimization


【解决方案1】:

子查询没有任何帮助,所以我会删除它们。

然后,将日期逻辑改写为直接比较。为此,我假设没有未来的日期。

最后,添加索引:

select . . .
from user u left join
     user_activity ua
     on ua.id = u.id and
        ua.start_timestamp >= dateadd(day, -7, convert(date, getdate()))
where u.start_timestamp >= dateadd(day, -7, convert(date, getdate()))

对于此查询,您需要user(start_timestamp)user_activity(id, start_timestamp) 上的索引。

第一个表的过滤条件放在where 子句中。对于后续表,它位于on 子句中。

还要注意有意义表别名的使用,而不是ab等任意字母。这使得查询更容易理解。

【讨论】:

    猜你喜欢
    • 2019-12-30
    • 2012-11-03
    • 2012-12-17
    • 2018-11-16
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 2011-01-06
    • 1970-01-01
    相关资源
    最近更新 更多