我将5年的数据集划分为季度表。我还有一个将它们连接在一起的主视图。当用户需要超过四分之一的数据时,他们通常使用主视图,而不是将多个季度连接在一起。
我的问题是,表值函数接受日期范围并仅返回必要分区中的记录会比查询整个主视图更快吗?
这是我目前的观点定义:
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 :(得分: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,并且执行计划也会显示出来。
如果手动创建日期分区查询,则可以
这是一个工作示例(即使没有索引)。请注意,Q1和Q4甚至没有显示在计划中。 披露:SQL Server 2008 R2 Express
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'
查询计划
处理日期范围时,从不(少数例外情况)使用日期列上的函数。这要求在与另一方进行比较之前,对表中的所有记录运行该函数。
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