我有两个要使用中间映射表连接的大表(以下结构的详细信息)。
我正在尝试加入t1.date = t2.date
和t1.id_a = int.id_a
和int.id_b = t2.id_b
上的所有三个
我还有一个where子句,用于将数据限制在date列的特定范围内(结果集为〜25k行)。
运行表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表示将这样做:
- 在t1上寻找聚集索引,寻找我的日期范围(费用为33%)
- 计算标量t.id_a(成本为0%)
- t2上的聚集索引查找,查找我的日期范围(费用为33%)
- 嵌套循环以加入[2]和[3](费用为0%)
- 在t_int上进行非聚集索引查找,查找t_int.id_a = t1.id_a和t_int.id_b = t2.id_b(费用为33%)
- 嵌套循环以加入[4]和[5](费用为0%)
- 计算标量t.date,t_int.id_b(成本为0%)
Table 1:
date,
id_a,
other columns
(320万行,日期和id_a是具有聚集索引的主键)
Table 2:
date,
id_b,
other columns
(1,850万行,日期和id_b是具有聚集索引的主键)
映射表:
id_a,
id_b,
other columns
(35,000行,id_b是具有聚集索引的主键,[id_a, id_b, other_col
上的其他非聚集索引)
没有其他索引,也没有约束(除了提到的主键约束)。
我已经在t2上重建了索引
有人可以帮我做什么吗?
答案 0 :(得分:0)
我已经在t2上重建了索引,因为它是零散的。但是我没有在t1或t_int上重建索引,因为它们看起来还不错。
感谢穆罕默德·穆哈巴蒂(Mohammad Mohabbati)在评论中的建议,我重新构建了所有内容,现在查询运行时间不到1秒。
因此,这里的答案可能对“重建所有索引,即使它们看起来不错”也可能有用,对其他遇到类似问题的人来说