【问题标题】:SQL Server : view MUCH slower than same query by itselfSQL Server:查看比单独查询慢得多
【发布时间】:2018-12-10 02:15:55
【问题描述】:

从这个 SO 答案来看,视图应该提供与直接使用相同查询相同的性能。

Is querying over a view slower than executing SQL directly?

我认为这是不正确的。

此查询针对视图

SELECT 
    * 
FROM 
    [Front].[vw_Details] k
WHERE 
    k.Id = 970435

需要 10 秒才能完成。从视图中复制查询并将WHERE k.Id = 970435 添加到其中只需不到 1 秒。视图没什么特别的,4 个LEFT JOINs,还有几个CASE 指令来清理数据。

我怎样才能弄清楚问题是什么,或者我需要用什么来完成这个问题才能回答这个问题?

更新 1:

【问题讨论】:

  • 第 1 步是查询计划。性能很多还取决于在哪里/如何这个查询被执行;普通的 SSMS 查询可能会通过常量选择来提升(这不适用于参数化查询或作为 SP 参数)。不断的选择可能会导致“非常不同/更好”的计划。
  • 无论如何,tldr:虽然 MSSQL 将视图内的 SQL 视为原始查询/计划的一部分,但它确实不保证与所述的逐字副本相同的计划选择视图 - 这是不同计划和性能配置文件的来源。
  • 添加了 SQL 版本和查询计划
  • 搜索 970435,它应该会显示“问题”。在快速/非视图情况下,它用于搜索(SeekPredicate)。
  • 嗯,你能不能帮我把它拼出来。我确实看到视图的执行计划具有“参数化”参数,但我不知道为什么这是不好的或我应该怎么做。

标签: sql-server tsql sql-server-2014


【解决方案1】:

您的查询计划不再可见,但如果您查看计划,您很可能会看到一个三角形抱怨基数估计和/或隐式声明。这意味着您正在以一种 SQL 引擎难以猜测键的方式连接表。

当您直接从查询运行时,它是即时的,可能是因为它不需要猜测您的密钥的大小是

例如:

k.Id = 970435 

SQLSERVER 已经知道它正在寻找 970435 一个 6 位数字。 它可以消除所有不是以 9 开​​头且没有 6 位数字的密钥。 :)

但是,从某种意义上说,它必须以一种考虑未知的方式来构建计划。因为它不知道自己可能持有什么样的钥匙。

请参阅 microsoft 了解可能对您有所帮助的各种示例和场景。

https://docs.microsoft.com/en-us/sql/relational-databases/query-processing-architecture-guide?view=sql-server-ver15

如果您一直在寻找 int,一种解决方法是使用 cast 或 convert 子句强制类型。根据您的数据,它可能会导致性能下降,但它是工具箱中的一个技巧,告诉 sql 不要尝试以 varchar(max) 或类似的方式查询计划。

SELECT * 
FROM  [Front].[vw_Details] k
WHERE TRY_CONVERT(INT,k.Id) = 970435

【讨论】:

    【解决方案2】:

    使用存储过程返回结果。存储过程使用索引,而视图通常不使用

    或

    使用表函数并查询表函数

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      • 2012-06-20
      • 2023-03-14
      • 2011-09-20
      • 1970-01-01
      • 2014-09-13
      相关资源
      最近更新 更多