TSQL-视图与存储过程:应用谓词时的性能注意事项

TSQL-视图与存储过程:应用谓词时的性能注意事项,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,假设我有一个定义如下的视图: CREATE VIEW [dbo].[vData_Values] AS SELECT ParentId, TimeStamp, Value From Table1 UNION ALL SELECT ParentId, TimeStamp, Value FROM Table2 UNION ALL SELECT ParentId, TimeStamp, Value FROM Table3 UNION ALL SELECT Par

假设我有一个定义如下的视图:

CREATE VIEW [dbo].[vData_Values] AS
   SELECT ParentId, TimeStamp, Value From Table1
   UNION ALL
   SELECT ParentId, TimeStamp, Value FROM Table2
   UNION ALL
   SELECT ParentId, TimeStamp, Value FROM Table3
   UNION ALL
   SELECT ParentId, TimeStamp, Value FROM Table4
   SELECT ParentId, TimeStamp, Value
   FROM vData_Values
   WHERE ParentId IN (...) and TimeStamp BETWEEN '1/1/2013' AND '3/31/2013 23:59'
假设我针对我的视图编写一个查询,如下所示:

CREATE VIEW [dbo].[vData_Values] AS
   SELECT ParentId, TimeStamp, Value From Table1
   UNION ALL
   SELECT ParentId, TimeStamp, Value FROM Table2
   UNION ALL
   SELECT ParentId, TimeStamp, Value FROM Table3
   UNION ALL
   SELECT ParentId, TimeStamp, Value FROM Table4
   SELECT ParentId, TimeStamp, Value
   FROM vData_Values
   WHERE ParentId IN (...) and TimeStamp BETWEEN '1/1/2013' AND '3/31/2013 23:59'
任何人都会期望对视图的查询的执行方式与存储过程不同,存储过程与视图具有相同的内部查询,但每个步骤都具有相同的WHERE子句。例如:

CREATE PROCEDURE [dbo].[GetValues]
(
...
)
AS
BEGIN

   SELECT ParentId, TimeStamp, Value From Table1
   WHERE ParentId IN (...) and TimeStamp BETWEEN '1/1/2013' AND '3/31/2013 23:59'
   UNION ALL
   SELECT ParentId, TimeStamp, Value FROM Table2
   WHERE ParentId IN (...) and TimeStamp BETWEEN '1/1/2013' AND '3/31/2013 23:59'
   UNION ALL
   SELECT ParentId, TimeStamp, Value FROM Table3
   WHERE ParentId IN (...) and TimeStamp BETWEEN '1/1/2013' AND '3/31/2013 23:59'
   UNION ALL
   SELECT ParentId, TimeStamp, Value FROM Table4
   WHERE ParentId IN (...) and TimeStamp BETWEEN '1/1/2013' AND '3/31/2013 23:59'

END
我正在尝试概念化这两个问题是否/如何以不同的方式处理/优化。将单个查询分块并对每个查询单独应用谓词是否会提高性能


谢谢。

我自己也有这个问题,发现存储过程版本快得多。我相信,我没有做太多的调查,但我相信,它将首先对所有记录进行合并,然后进行过滤。存储过程过滤每个片段,然后合并它们,因此假设记录较少

现在我没有尝试的是一个包含重复项的并集,大概不会检查值

因此,不幸的是,如果您要处理大量的记录,在您显示的两个示例之间,存储的过程会更快。我说很遗憾,因为您必须预先构建where子句


试着看一下执行计划,看看上面写着什么,我也很好奇。

比较一下执行计划

以下是相同的执行计划

  CREATE VIEW [dbo].[docSVsysInt] AS
  select sID 
  from docSVsys 
  union 
  select sID 
  from docSVint

  select sID 
  from [docSVsysInt] 
  where sID > 100000 and sID <  100010

  select sID 
  from docSVsys 
  where sID > 100000 and sID <  100010
  union 
  select sID 
  from docSVint
  where sID > 100000 and sID <  100010

  select sID 
  from
  (
  select sID 
  from docSVsys 
  union 
  select sID 
  from docSVint
  )  comb
  where sID > 100000 and sID <  100010

检查执行计划。在本例中,我希望SQLServer在推送谓词时不会有任何困难。此外,您还应该为日期时间文字使用明确的日期格式,并且可能不在两者之间,除非时间绝对不以秒存储。