1

例如,现在我有一个查询,例如:

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 显示它首先将 A1 与 A2 左连接,然后将结果与 A3 继续左连接......并且在左连接 20 个表后,估计的行数没有改变( 210 万)

但是,如果我将查询更改为:

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 服务器显示它将首先将连接 A1 与 A3,然后与 A4、A6、A7、A8、A10...A20 然后 A2、A17...关于估计的行数,在连接 13 之后表,估计行数没有改变,但之后,每次加入另一个表,估计行数急剧增加,从 200 万到 2,6 然后 3,8.. 加入 20 表后变为 83百万。

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

4

1 回答 1

0

您的演员完全有可能在统计数据方面混淆了查询优化器 - 因为字符串排序 '201' 将介于 '2' 和 '3' 之间 - 而对于 bigint 则不会。所以,同样地,如果你有一个从 '1000' 到 '2' 的字符串范围——那么作为一个 bigint 范围就没有多大意义了。

我会强烈考虑存储数据的整数版本,以便存储的统计信息有意义,然后您可能会从查询优化器中获得更好的值。

于 2013-07-23T08:03:43.060 回答