微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么并行性会影响我的查询是否成功?

如何解决为什么并行性会影响我的查询是否成功?

本周遇到了一个奇怪的问题,即查询第一次失败。它是存储过程的一部分,这就是它失败的地方。 (我将字段更改为通用内容

查询

SELECT 
p.Type,CAST(c.Comment AS int) AS NumberOfComments
FROM Comments c
JOIN Pages p ON c.Id = p.Id
WHERE c.CommentNo = 5 AND p.Type IN ('AAA','BBB','CCC')

错误信息是

将 varchar 值“Test Text In here”转换为数据类型 int 时转换失败。

使用通常的执行顺序,我希望 WHERE 在 SELECT CAST 之前执行,但在这种情况下没有发生。在 Comments 表的 Clustered Index Scan 之后,有一个 Compute Scalar 在其中执行 Cast,然后对 Pages 表执行哈希匹配。

注释字段不仅用于数字,而且这些特定类型的所有注释始终是数字。我们使用 TRY_CAST 而不是 CAST 来修复它,但我也注意到查询本身已经并行。

当我添加 OPTION (MAXDOP 1) 时,查询成功运行。执行计划除了Parallelism外都是一样的,所以使用了类似的计划。

所以我想我的问题是为什么 Parallelism 会导致此查询失败?

解决方法

SQL 是一种查询语言,与过程语言无关。 在过程语言中,您可以通过对代码段进行排序以对每个部分进行排序来控制每条指令的顺序。这被称为“如何”代码...... 在查询语言中,您只指定“什么”代码,而不是如何,查询被翻译成不同的指令序列(如何代码)来完成您的请求,然后根据您的需求来评估每种不同的解决方案成本,最后优化器选择将要执行的最好的一个。

有时,由于查询中的细微差异、会话执行参数、数据值的分布,代码的更改方式...

所以你永远不要假设一个查询会以同样的方式执行。您需要通过消除误解的逻辑来保护您的查询...

,

原因是您的 c.Comment 值不是数字。所以,转换失败。 即使在 WHERE 子句中过滤掉了行,也可能发生这种情况。

此外,子查询、CTE 和视图也无济于事。为什么不?因为 SQL 优化器可以重新安排处理。在这种情况下,它可以决定在过滤行之前将转换“推送”到更靠近数据源的位置。

微软认为这是一个错误(实际上,它是一个“优化功能”),尽管我认为它是一个错误。但是有一种非常简单的方法可以使用 TRY_CAST():

SELECT p.Type,TRY_CAST(c.Comment AS int) AS NumberOfComments
FROM Comments c JOIN
     Pages p
     ON c.Id = p.Id
WHERE c.CommentNo = 5 AND p.Type IN ('AAA','BBB','CCC');

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。