我有两个大表,我正在使用一个中间映射表连接它们(下面是结构的详细信息(。
我正在尝试加入t1.date = t2.date
、t1.id_a = int.id_a
和int.id_b = t2.id_b
上的所有三个
我还有一个where子句,它将数据限制在日期列的一个非常特定的范围内(结果集为~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.ida(成本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万行,date和id_a是带聚集索引的主键(
Table 2:
date,
id_b,
other columns
(18.5米行,日期和id_b是带聚集索引的主键(
映射表:
id_a,
id_b,
other columns
(35k行,id_b是主键w聚集索引,[id_a, id_b, other_col
]上的附加非聚集索引(
没有其他索引,也没有任何约束(除了提到的主键约束(。
我已经在t2 上重建了索引
有人能帮我做什么吗?
我已经在t2上重建了索引,因为它是碎片化的。但我没有在t1或t_int上重建索引,因为它们看起来很好。
多亏了Mohammad Mohabati在评论中的建议,我重新构建了它们,现在查询只需不到1秒。
因此,这里的答案可能对其他有类似问题的人有用,是"重建所有索引,即使它们看起来很好">