如何优化多个(大)表的连接
How to optimize join of multiple (large) tables
我正在尝试使用 SQL 服务器中的 LEFT OUTER
加入多个 table。在下面的示例中,左侧的 table 并没有那么大,但右侧的 table 大约有 4-5 百万行,这只是两个 table。还有 3 个 table 需要加入,它们相当大 table。
-- 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 查询非常慢并且需要很长时间。有没有办法优化连接?
子查询没有任何帮助,所以我会删除它们。
然后,将日期逻辑改写为直接比较。为此,我假设没有未来的日期。
最后,添加索引:
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)
上建立索引。
第一个 table 的过滤条件在 where
子句中。对于随后的 tables,它进入 on
子句。
另请注意使用 有意义的 table 别名,而不是 a
和 b
等任意字母。这使得查询更容易理解。
我正在尝试使用 SQL 服务器中的 LEFT OUTER
加入多个 table。在下面的示例中,左侧的 table 并没有那么大,但右侧的 table 大约有 4-5 百万行,这只是两个 table。还有 3 个 table 需要加入,它们相当大 table。
-- 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 查询非常慢并且需要很长时间。有没有办法优化连接?
子查询没有任何帮助,所以我会删除它们。
然后,将日期逻辑改写为直接比较。为此,我假设没有未来的日期。
最后,添加索引:
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)
上建立索引。
第一个 table 的过滤条件在 where
子句中。对于随后的 tables,它进入 on
子句。
另请注意使用 有意义的 table 别名,而不是 a
和 b
等任意字母。这使得查询更容易理解。