【发布时间】:2021-11-13 00:36:00
【问题描述】:
我遇到了一个严重的问题,导致我无法在 SQL Server 中使用视图。问题是使用视图时,我经常遇到超时异常。令人惊讶的是,每当我改变视图时,错误就会消失一段时间。
我的示例视图如下 - 假设我有两个表,Product 和 ProductTranslation。 Product 表包含产品表的主要详细信息,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