【问题标题】:SQL Server views getting timeout periodicallySQL Server 视图定期超时
【发布时间】:2021-11-13 00:36:00
【问题描述】:

我遇到了一个严重的问题,导致我无法在 SQL Server 中使用视图。问题是使用视图时,我经常遇到超时异常。令人惊讶的是,每当我改变视图时,错误就会消失一段时间。

我的示例视图如下 - 假设我有两个表,ProductProductTranslationProduct 表包含产品表的主要详细信息,ProductTranslation 包含产品名称和其他语言描述的翻译。

CREATE VIEW myview 
AS
    SELECT
        p.productid AS productId,
        COALESCE(pt.prName, p.prName) AS prName,
        COALESCE(pt.prDesc, p.description) AS prDesc,
        '2' AS langId
    FROM
        Product p 
    LEFT JOIN 
        ProductTranslation pt ON p.productId = pt.productId AND pt.langId = 2
        
    UNION

    SELECT
        productId, prName, description AS prDesc, '1' AS langId  
    FROM
        itecom.Product

product 表和 productTranslation 表会经常更新。

我会在很多连接中使用这个视图来获得预期的结果:

SELECT ... 
FROM
    <joins> 
LEFT JOIN
    myview pt ON p.productId = pt.productId AND pt.langId = @lang

最初它按预期工作,但一段时间后连接查询将抛出超时异常。如前所述,一旦我更改了视图语句(不修改任何视图代码),连接查询再次顺利运行。

谁能在这里解决这个问题。谢谢

【问题讨论】:

  • 如果您正在寻找性能,我建议您不要使用视图。问题通常有两个方面:1) 开发人员不了解使用视图的成本,因此他们不恰当地使用它,以及 2) 一些数据库引擎不擅长优化使用视图的查询。只有当视图碰巧有聚合、子查询、数据实体化、联合和/或外连接时,情况才会更糟。更糟糕的是,开发人员忘记将视图的 DDL 保存在源代码存储库中,因此它们是“未版本化的”。
  • 我会提到嵌套视图通常是一个性能问题,但根据您问题中的信息,情况似乎并非如此。在重新创建视图之前,症状先快后慢,这表明经典的参数嗅探,这可能是有或没有视图的问题。避免这种情况的一种方法是将OPTION(RECOMPILE) 查询提示添加到最外层查询(即使用视图的查询)。
  • 自 2000 年以来的任何版本的 SQL Server 中,视图或优化它们都没有问题。视图不会导致性能问题,但使用它们糟糕的查询、未索引的表等也很糟糕。
  • 并将“UNION”更改为“UNION ALL”,因为查询之间没有重复项。
  • 至于它为什么起作用然后突然停止工作的实际问题-我怀疑这与统计数据有关。当您更改视图时,您会强制 SQL Server 重新生成统计信息,您现在可以获得更好的计划。确保您有适当的流程来更频繁地更新统计信息。

标签: sql sql-server view timeoutexception


【解决方案1】:

UNION 会产生删除重复项的开销。您知道子查询之间没有重复,因为langId 不同。所以你可能可以使用:

SELECT p.productid AS productId,
       COALESCE(pt.prName, p.prName) AS prName,
       COALESCE(pt.prDesc, p.description) AS prDesc,
       '2' AS langId
FROM Product p LEFT JOIN 
     ProductTranslation pt
     ON p.productId = pt.productId AND pt.langId = 2        
UNION ALL
SELECT productId, prName, description AS prDesc, '1' AS langId  
FROM itecom.Product;

如果您需要删除子查询的重复项,您可以使用SELECT DISTINCT。这允许优化器使用特定于每个子查询的索引进行重复删除。

【讨论】:

    猜你喜欢
    • 2023-03-04
    • 2012-06-01
    • 2018-06-19
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 2019-07-02
    • 1970-01-01
    • 2010-09-27
    相关资源
    最近更新 更多