2013-07-23 150 views
1

例如的估计数,现在我有这样一个查询:SQL Server的执行计划和行

select * from A1 left join A2 on A1.Column1 = A2.Column1 
left join A3 on A1.Column2 = A3.Column2 
left join A4 on A1.Column3 = A4.Column3 
.... 
left join A20 on A1.Column4 = A20.Column4 

当我查看上面的查询的执行计划时,SQL Server表明它首先会留下A2加入A1 ,然后继续留下参加与A3的结果...之后左连接20个表,行的估计数没有改变(2,1百万)

但是,如果我改变我的查询:

select * from A1 left join A2 on Cast(A1.Column1 as bigint) = Cast(A2.Column1 as bigint) 
left join A3 on Cast(A1.Column2 as bigint) = Cast(A3.Column2 as bigint) 
left join A4 on Cast(A1.Column3 as bigint) = Cast(A4.Column3 as bigint) 
.... 
left join A20 on Cast(A1.Column4 as bigint) = Cast(A20.Column4 as bigint) 

注:我所有的列可以被转换为bigint,因为它只包含数字,但有时它具有前导零,所以我必须让它的数据类型为varchar。

现在,通过这个查询,SQL服务器显示它首先将A3连接到A1,然后是A4,A6,A7,A8,A10 ... A20,然后是A2,A17 ...关于估计的行数,加入13个表后,估计的行数没有变化,但之后,每次它加入另一个表时,估计的行数急剧增加,从2百万增加到2,6,然后3,8 ..加入后20它变成了83百万。

任何人都可以解释为什么是这样呢?在我的第二个查询中,为什么Sql server会像这样随机地连接表?什么可以使估计的行数突然增加?

+1

不是一个答案,但在加盟整数数量级不是加入对字符串快... –

+0

是的,我知道,这就是为什么我试着投我的专栏为int的原因。它确实使联接性能提高很多。但完成后加入,我要的结果插入到表中,因为行的估计数目那样急剧增加,它耗费了大量的时间整理,并插入到新表,甚至慢于不强制转换为int。 – user2500561

+0

有几件事情要检查。首先每张桌上有多少数据可用?也许你的第一张桌子有1亿张唱片,虽然前13张桌子只有20张,但接下来的7张桌子其他8000万张唱片呢?我建议先创建几行表并验证您的数据是否正确。 –

回答

0

是完全可能的,你投是混淆查询优化方面的统计数据 - 与字符串排序“201”将是“2”和“3”之间 - 而对于BIGINT也不会。所以,同样,如果你有一个从'1000'到'2'的字符串范围 - 那么作为一个bigint范围没有多大意义。

我会认真考虑存储数据的整数版本,以及,使该存储可以是有意义的,而统计数据,那么你很可能会得到更好的价值观出了查询优化器。