Sql server 2005 SQL Server 2008动态跨数据库视图
我们在SQLServer2008R2 SE中有一个名为AVL的数据库。这个数据库有许多表,但有一个特别称为ASSETLOCATION的表,它现在有4600万行,占数据库总大小的99.9% 此表包含2008年至今的信息,实际增长率约为每天12万条记录。 现在,我们要解决两种情况:Sql server 2005 SQL Server 2008动态跨数据库视图,sql-server-2005,sql-server-2008,Sql Server 2005,Sql Server 2008,我们在SQLServer2008R2 SE中有一个名为AVL的数据库。这个数据库有许多表,但有一个特别称为ASSETLOCATION的表,它现在有4600万行,占数据库总大小的99.9% 此表包含2008年至今的信息,实际增长率约为每天12万条记录。 现在,我们要解决两种情况: 性能开始慢慢下降,而且一切都很好 优化了,所以没什么可做的 备份时间在增加,并且正在成为一个问题(我们只做1次完整备份) 每天备份)。winrar完成他的工作后,BAK文件是11GB 最终大小为2GB,然后脚本将文件发
- 性能开始慢慢下降,而且一切都很好 优化了,所以没什么可做的
- 备份时间在增加,并且正在成为一个问题(我们只做1次完整备份) 每天备份)。winrar完成他的工作后,BAK文件是11GB 最终大小为2GB,然后脚本将文件发送到异地。我们有 一个T1和拉2GB通过电线大约需要5个小时
select * from vASSETLOCATION where [WHEN] between '2008-01-01' and '2008-01-02'
CREATE PROCEDURE dbo.DetermineViews
@StartDate DATETIME,
@EndDate DATETIME,
@optionalToday BIT = 0
AS
BEGIN
SET NOCOUNT ON;
DECLARE @sql NVARCHAR(MAX) = N'';
SET @sql = @sql + N'SELECT * FROM ' + CASE
WHEN @StartDate >= '20080101' AND @EndDate < '20090101' THEN 'AVL2008.dbo.ASSETLOCATION'
WHEN @StartDate >= '20080101' AND @EndDate < '20100101' THEN 'dbo.vAL_2008_2009'
WHEN @StartDate >= '20080101' AND @EndDate < '20110101' THEN 'dbo.vAL_2008_2010'
-- etc. etc.
WHEN YEAR(@StartDate) = YEAR(CURRENT_TIMESTAMP) THEN 'AVL.dbo.ASSETLOCATION'
ELSE '' END;
IF @OptionalToday = 1 AND YEAR(@StartDate) <> YEAR(CURRENT_TIMESTAMP)
BEGIN
SET @sql = @sql + N'UNION ALL SELECT * FROM AVL.dbo.ASSETLOCATION'
END
SET @sql = @sql + ' WHERE [WHEN] BETWEEN '''
+ CONVERT(CHAR(8), @StartDate, 112) + ''' AND '''
+ CONVERT(CHAR(8), @EndDate, 112) + '''';
IF @OptionalToday = 1
BEGIN
SET @sql = @sql + ' OR ([WHEN] >= DATEDIFF(DAY, 0, CURRENT_TIMESTAMP)
AND [WHEN] < DATEADD(DAY, 1, DATEDIFF(DAY, 0, CURRENT_TIMESTAMP)';
END
PRINT @sql;
-- EXEC sp_executeSQL @sql;
END
GO
在这种情况下,视图应该只访问AVL2008.ASSETLOCATION表
select * from vASSETLOCATION where [WHEN] between '2008-12-29' and '2009-01-05'
在这种情况下,视图应该访问AVL2008.ASSETLOCATION和AVL2009.ASSETLOCATION
select * from vASSETLOCATION where
([WHEN] between '2008-01-01' and '2008-01-01')
or
([WHEN] = getdate())
在这种情况下,视图应访问AVL2008.ASSETLOCATION和AVL.ASSETLOCATION
我知道用表标量UDF代替视图可以解决这个问题,但是有4个以上的字段,[WHEN]并不是我们希望在where部分中包含的唯一字段。
在任何人提出建议之前,表分区功能可能会有助于提高性能,但不会解决备份问题
在视图中是否有这样做的方法?
谢谢。-这听起来像是or的经典案例 但是,您可以使用一些智能代码来解决这个问题,而无需为Enterprise edition(企业版)支付价格(或进行支持这些功能所需的所有准备工作),这些代码对问题的看法略有不同。您不希望一个视图访问不同数据库中的所有表,但是如果您有多个视图和一个存储过程来控制如何访问它们呢 为最常见的访问模式创建视图。也许您的视图涵盖了2008-2010、2008-2009、2009-2010等的日期范围。它们可能如下所示:
CREATE VIEW dbo.vAL_2008_2009
AS
SELECT * FROM AVL2008.dbo.ASSETLOCATION
UNION ALL
SELECT * FROM AVL2009.dbo.ASSETLOCATION;
GO
CREATE VIEW dbo.vAL_2008_2010
AS
SELECT * FROM AVL2008.dbo.ASSETLOCATION
UNION ALL
SELECT * FROM AVL2009.dbo.ASSETLOCATION
UNION ALL
SELECT * FROM AVL2010.dbo.ASSETLOCATION;
GO
-- etc. etc.
现在,处理查询的代码可以获取输入日期参数并计算需要查询的视图。例如:
select * from vASSETLOCATION where [WHEN] between '2008-01-01' and '2008-01-02'
CREATE PROCEDURE dbo.DetermineViews
@StartDate DATETIME,
@EndDate DATETIME,
@optionalToday BIT = 0
AS
BEGIN
SET NOCOUNT ON;
DECLARE @sql NVARCHAR(MAX) = N'';
SET @sql = @sql + N'SELECT * FROM ' + CASE
WHEN @StartDate >= '20080101' AND @EndDate < '20090101' THEN 'AVL2008.dbo.ASSETLOCATION'
WHEN @StartDate >= '20080101' AND @EndDate < '20100101' THEN 'dbo.vAL_2008_2009'
WHEN @StartDate >= '20080101' AND @EndDate < '20110101' THEN 'dbo.vAL_2008_2010'
-- etc. etc.
WHEN YEAR(@StartDate) = YEAR(CURRENT_TIMESTAMP) THEN 'AVL.dbo.ASSETLOCATION'
ELSE '' END;
IF @OptionalToday = 1 AND YEAR(@StartDate) <> YEAR(CURRENT_TIMESTAMP)
BEGIN
SET @sql = @sql + N'UNION ALL SELECT * FROM AVL.dbo.ASSETLOCATION'
END
SET @sql = @sql + ' WHERE [WHEN] BETWEEN '''
+ CONVERT(CHAR(8), @StartDate, 112) + ''' AND '''
+ CONVERT(CHAR(8), @EndDate, 112) + '''';
IF @OptionalToday = 1
BEGIN
SET @sql = @sql + ' OR ([WHEN] >= DATEDIFF(DAY, 0, CURRENT_TIMESTAMP)
AND [WHEN] < DATEADD(DAY, 1, DATEDIFF(DAY, 0, CURRENT_TIMESTAMP)';
END
PRINT @sql;
-- EXEC sp_executeSQL @sql;
END
GO
创建过程dbo.DetermineViews
@开始日期时间,
@EndDate日期时间,
@可选当前位=0
作为
开始
不计数;
声明@sql NVARCHAR(MAX)=N';
SET@sql=@sql+N'SELECT*FROM'+CASE
当@StartDate>='20080101'和@EndDate<'20090101'时,则为'AVL2008.dbo.ASSETLOCATION'
当@StartDate>='20080101'和@EndDate<'20100101'时,则为'dbo.vAL_2008_2009'
当@StartDate>='20080101'和@EndDate<'20110101'时,则为'dbo.vAL\u 2008\u 2010'
--等等等等。
当YEAR(@StartDate)=YEAR(当前时间戳)时,则为“AVL.dbo.ASSETLOCATION”
否则“结束”;
如果@OptionalToday=1和年份(@StartDate)年份(当前时间戳)
开始
SET@sql=@sql+N'UNION ALL SELECT*FROM AVL.dbo.ASSETLOCATION'
结束
设置@sql=@sql+,其中[何时]介于“”之间
+转换(字符(8),@StartDate,112)+“和”
+转换(字符(8),@EndDate,112)+'';
如果@OptionalToday=1
开始
设置@sql=@sql+”或([WHEN]>=DATEDIFF(天,0,当前时间戳)
和[当]
我可能遗漏了您的一些业务逻辑,您肯定想在其中添加一些错误处理,并测试其中的垃圾,但这是一个相对容易维护的解决方案,只需要在创建新数据库以存档去年的数据时进行更新,这听上去好像每年只发生一次。a t参考您关于表分区的评论,如果您使用分区方案将数据分散到不同的文件组,然后单独备份文件组(可能在不同的方案上),这可能会有助于解决备份问题。至少要注意一些事情。@WT\W绝对地,分区不一定意味着“备份是巨大的”…当然有办法布置分区和文件组,以便旧数据是只读的,而不是活动备份例程的一部分。+1表示聪明!但我需要大量更改使用AL表的所有SP。例如,当前sql类似于“从AL中选择最大值(何时),其中IDASSET=1和[WHEN]“在x和y之间”将需要大量的工作才能转换为这种方法。这看起来很像一种表标量UDF方法,但被包装在SP中。好吧,我很想让你有信心