-1

我有两个使用中间映射表加入的大表(下面的结构细节)。

我正在尝试加入所有t1.date = t2.date三个t1.id_a = int.id_aint.id_b = t2.id_b

我还有一个 where 子句,它将数据限制在日期列的一个非常特定的范围内(结果集是~25k rows)。

运行表 1 和 int 表的连接(使用 where 子句)或表 2 和 int 表的连接(使用 where 子句)每个都需要 2 秒。然后连接这两个结果集应该很简单,表 1 大约有 37k 行,表 2 大约有 200k 行。

相反,此查询始终需要 8 分钟:

select t1.date, t1.id_b, t1.other_cols, t2.other_cols
from t1 
inner join t_int on t1.id_a = t_int.id_a
inner join t_2 on t2.date = t1.date and t2.id_b = t_int.id_b
where t1.date between '2018-10-21' and '2018-12-10'

在估计的(和实际的)执行计划中,SQL Server 说它会:

  1. 在 t1 上寻找聚集索引,寻找我的日期范围(成本 33%)
  2. 计算标量 t.id_a(成本 0%)
  3. 在 t2 上寻找聚集索引,寻找我的日期范围(成本 33%)
  4. 连接 [2] 和 [3] 的嵌套循环(成本 0%)
  5. 在 t_int 上寻找非聚集索引,寻找 t_int.id_a = t1.id_a 和 t_int.id_b = t2.id_b(成本 33%)
  6. 连接 [4] 和 [5] 的嵌套循环(成本 0%)
  7. 计算标量 t.date、t_int.id_b(成本 0%)
Table 1:
date,
id_a,
other columns

(3.2m 行,date 和 id_a 是主键 w 聚集索引)

Table 2:
date,
id_b,
other columns

(1850 万行,日期和 id_b 是主键 w 聚集索引)

映射表:

id_a,
id_b,
other columns

(35k 行,id_b 是主键 w 聚集索引,[ id_a, id_b, other_col] 上的附加非聚集索引)

没有其他索引,也没有任何约束(除了提到的主键约束)。

我已经在 t2 上重建了索引

任何人都可以帮助我需要做的事情吗?

4

1 回答 1

0

我已经在 t2 上重建了索引,因为它是碎片化的。但是我没有在 t1 或 t_int 上重建索引,因为它们看起来不错。

感谢 Mohammad Mohabbati 在评论中的建议,我重新构建了它们,现在查询运行时间不到 1 秒。

所以这里的答案可能对其他有类似问题的人有用,是“重建所有索引,即使它们看起来不错”

于 2018-12-11T05:13:25.273 回答