2011-02-10 44 views
2

我有一个5年的数据集分为季度表。我也有一个主视图,将它们连接在一起。当用户需要超过四分之一的数据时,他们经常使用主视图,而不是将多个小区连接在一起。SQL Server表值功能性能

我的问题是,一个表值函数接受日期范围,并只返回来自必要分区的记录比查询整个主视图更快?

这是我当前视图定义:

ALTER VIEW [dbo].[loandetails_test] 
AS 
SELECT  * 
FROM   loandetails05 
where year(date) = 2005 
UNION 
SELECT  * 
FROM   loandetails06 
where year(date) = 2006 
UNION 
SELECT  * 
FROM   loandetails07 
where year(date) = 2007 
UNION 
SELECT  * 
FROM   loandetails08 
where year(date) = 2008 
UNION 
SELECT  * 
FROM   loandetails1q09 
where date >= '1/1/2009' and date < '4/1/2009' 
UNION 
SELECT  * 
FROM   loandetails2q09 
where date >= '4/1/2009' and date < '7/1/2009' 
UNION 
SELECT  * 
FROM   loandetails3q09 
where date >= '7/1/2009' and date < '10/1/2009' 
UNION 
SELECT  * 
FROM   loandetails4q09 
where date >= '10/1/2009' and date < '1/1/2010' 
UNION 
SELECT  * 
FROM   loandetails1q10 
where date >= '1/1/2010' and date < '4/1/2010' 
UNION 
SELECT  * 
FROM   loandetails2q10 
where date >= '4/1/2010' and date < '7/1/2010' 
UNION 
SELECT  * 
FROM   loandetails3q10 
where date >= '7/1/2010' and date < '10/1/2010' 
UNION 
SELECT  * 
FROM   loandetails4q10 
where date >= '10/1/2010' and date < '1/1/2011' 
union 
SELECT  * 
FROM   loandetails_CURRENT 
where date >= '1/1/2011' and date < '4/1/2011' 


GO 
+0

可能。这当然很大程度上取决于如何编写表值函数。但唯一的方法是使用主视图和使用表值函数来衡量性能。 – HLGEM 2011-02-10 18:47:40

回答

2

答案应该是坚实的没有。

分区使用隐式标准进行设置,因此如果您按日期(季度)进行分区,SQL Server就会知道哪些分区将满足查询(假设查询将具有日期过滤器)。检查确认两个(或涉及到的分区)之间的流合并的执行计划。

我有一个情况,N个数据库中的表(是每个筒仓一个)在主视图中加入,就像您一样。该master view使用为每一个过滤器,特别是它看起来像这样

select source=1, col1, col2, col3 
from db1.dbo.tbl 
union all 
select source=2, col1, col2, col3 
from db2.dbo.tbl 
etc 

,要求为where source in (2,3)任何查询自动识别,只有2 DBS需要进行搜索,并执行计划显示为多。

如果是手动创建日期分区的查询,可以

  1. 对日期范围的索引,每个表中
  2. 力优化识别分区

这里一个工作示例(即使没有索引)。请注意,Q1和Q4甚至没有在计划中显示。 披露:SQL Server 2008 R2的快速

select dateadd(d, number, '20100101') TheDate, * 
into Q1data 
from master..spt_values 
where type='p' and number between 1 and 370 
and datepart(quarter, dateadd(d, number, '20100101')) =1 

select dateadd(d, number, '20100101') TheDate, * 
into Q2data 
from master..spt_values 
where type='p' and number between 1 and 370 
and datepart(quarter, dateadd(d, number, '20100101')) =2 

select dateadd(d, number, '20100101') TheDate, * 
into Q3data 
from master..spt_values 
where type='p' and number between 1 and 370 
and datepart(quarter, dateadd(d, number, '20100101')) =3 

select dateadd(d, number, '20100101') TheDate, * 
into Q4data 
from master..spt_values 
where type='p' and number between 1 and 370 
and datepart(quarter, dateadd(d, number, '20100101')) =4 
GO 

create view Ydata 
with schemabinding 
as 
select TheDate, name, number, TYPE, LOW, high, status 
from dbo.Q1Data where TheDate >= '20100101' and TheDate < '20100401' 
union all 
select TheDate, name, number, TYPE, LOW, high, status 
from dbo.Q2Data where TheDate >= '20100401' and TheDate < '20100701' 
union all 
select TheDate, name, number, TYPE, LOW, high, status 
from dbo.Q3Data where TheDate >= '20100701' and TheDate < '20101001' 
union all 
select TheDate, name, number, TYPE, LOW, high, status 
from dbo.Q4Data where TheDate >= '20101001' and TheDate < '20110101' 
GO 

select * from YData where TheDate between '20100601' and '20100831' 

查询计划

enter image description here

回复:更新问题

当日期范围处理,NEVER(除少数例外)使用日期栏中的功能。这要求函数在与另一边比较之前针对表中的所有记录运行。

where year(date) = 2005 
===> means scan the table, for each row take the year, compare to 2005 

不如写成

where date >= '20050101' and date < '20060101' 
===> means given a date range, use the index to seek the range 
+0

我的查询计划显示索引寻找查询中日期范围不必要的分区。我应该指定这些不是由SQL Server创建的分区,因为我没有Enterprise Edition。他们是我手动创建的。 – Colin 2011-02-10 18:59:30