【问题标题】:SQL Server execution plan and estimated number of rowsSQL Server 执行计划和估计行数
【发布时间】:2013-07-23 04:58:00
【问题描述】:

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

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 个表后,估计行数没有' t 改变(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..and after join 20 table变成了 8300 万。

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

【问题讨论】:

  • 不是一个答案,但是,加入整数比加入字符串要快几个数量级......
  • 是的,我知道,这就是我尝试将列转换为 int 的原因。它确实使连接性能提高了很多。但是在完成连接之后,我必须将结果插入到一个表中,并且因为估计的行数会像这样急剧增加,所以排序和插入到新表需要花费大量时间,甚至比不强制转换为 int 还要慢。
  • 有几件事要检查。首先每个表有多少数据可用?也许你的第一个表有 1 亿条记录,虽然前 13 个表只匹配 20 个,但接下来的 7 个表匹配其他 8000 万条记录?我建议首先创建几行表并验证您的数据是否正确。
  • 您可以添加一个persisted computed column 来将已转换的列保存为int 或bigint 吗?它应该有助于提高性能。

标签: sql-server casting sql-execution-plan


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-06
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 2021-12-09
    • 1970-01-01
    相关资源
    最近更新 更多