2011-08-25 2 views
3

SQL Server 2008 R2 SE에는 AVL이라는 데이터베이스가 있습니다. 이 데이터베이스에는 많은 테이블이 있지만, 특히 4600 만 행이 있고 총 데이터베이스 크기의 99.9 %를 차지하는 ASSETLOCATION이라는 테이블이 있습니다.SQL Server 2008 동적 교차 데이터베이스보기

이 테이블에는 2008 년까지의 정보가 있으며 실제 성장률은 매일 약 120,000 레코드입니다. 이제이 이 상황이 우리가 해결하고자 다음과 같습니다

  • 성능이 서서히 저하되기 시작하고, 모든
  • 백업 시간이 증가 할 일이 많이 없다 그래서 을 최적화하고 (우리 문제가되고있다 전체 1 분 백업을 수행하십시오. winrar가 자신의 일을 최종 크기 2GB로 만든 후 BAK 파일이 11GB이고 스크립트가 오프 사이트 파일을 보냅니다. 우리는 T1을 가지고 있고 철사를 통해 2GB를 당기는 것은 약 5 시간이 걸리고 있습니다.

이 모든 것이 정상이지만 여기에 대문자를 쓰고 싶습니다. + 90 %의 SQL 문은 3 개월 이하의 정보 만 사용합니다. 즉, 2008 년, 2009 년 및 2010 년의 데이터는 얻을 수 없습니다. 자주 액세스했습니다.

나는 매년 새로운 데이터베이스를 만들려고했다. 말할 수 : - AVL2008 데이터베이스가 전용 테이블 레코드에 ASSETLOCATION가있을 것입니다 2008 에서 - AVL2009 데이터베이스, 테이블 만 2009 에서 레코드와 ASSETLOCATION가있을 것입니다 - AVL2010 데이터베이스, 테이블 만 2010

에서 레코드와 ASSETLOCATION가있을 것입니다

과거 데이터를 이미 추측 했으므로 변경되지 않으므로 AVL 데이터베이스에 현재 연도의 레코드 만 포함되므로 백업 관점에서 볼 때이 값이 좋습니다. 이 접근법은 또한 많은 성과를 도울 것입니다.

지금 문제가 있습니다. ASSETLOCATION 테이블은 다음과 같은 열이라고 가정 - IDASSETLOCATION (INT, PK 아이덴티티) - IDASSET (INT, FK ASSET 테이블) - (날짜) - LATLONG을 (VARCHAR (22), 공간 정보)

AVL 데이터베이스에서 "vASSETLOCATION"이라는보기를 만들 필요가 있습니다. 마녀는 매우 간단합니다. 하지만 모든 데이터베이스에 액세스하고 UNSONY을 통해 ASSETLOCATION 테이블에 가입하는 것을 원하지 않습니다. WHEN 필드. 예를 들어이 경우

select * from vASSETLOCATION where [WHEN] between '2008-01-01' and '2008-01-02' 

보기는 단지보기 AVL2008.ASSETLOCATION 및 AVL2009.ASSETLOCATION

select * from vASSETLOCATION where 
    ([WHEN] between '2008-01-01' and '2008-01-01') 
or 
    ([WHEN] = getdate()) 
액세스한다이 경우 AVL2008.ASSETLOCATION 테이블

select * from vASSETLOCATION where [WHEN] between '2008-12-29' and '2009-01-05' 

액세스해야

이 경우 뷰는 AVL2008.ASSETLOCATION 및 AVL.ASSETLOCATION에 액세스해야합니다.

뷰 대신 스칼라 UDF 테이블을 사용하여 문제를 해결할 수 있습니다. 그러나 4 개 필드 이상이 있고 [WHEN]은 where 부분에 포함시킬 수있는 유일한 필드가 아닙니다. 누군가가 제안하기 전에, 테이블 파티셔닝 기능은 성능면에서 도움이되지만 백업 문제에서는 도움이되지 않습니다.

보기에서이를 수행 할 방법이 있다면? 감사합니다.

+1

테이블 분할에 대한 의견과 관련하여 생각하면 파티션 구성표를 사용하여 다른 파일 그룹에 데이터를 분산시킨 다음 파일 그룹을 개별적으로 (그리고 잠재적으로 다른 구성표에) 백업하면 백업 문제를 해결할 수 있습니다. 적어도 들여다 볼만한 것. –

+0

@WT_W 절대적으로 파티셔닝은 반드시 "백업이 거대 함"을 의미하지는 않습니다 ... 파티션 및 파일 그룹을 배치하여 이전 데이터가 읽기 전용이며 활성 백업 루틴의 일부가되지 않도록하는 방법은 확실합니다. –

답변

2

이것은 table partitioning 또는 distributed partitioned views의 전형적인 경우와 같습니다.

그러나 문제를 약간 다르게 보는 스마트 코드를 사용하여 Enterprise 버전의 가격을 조율하지 않고 (또는 해당 기능을 지원하는 데 필요한 모든 준비 작업을 수행하지 않고도)이 문제를 해결할 수 있습니다. 서로 다른 데이터베이스에서 모든 테이블에 액세스하는 단일보기는 원하지 않지만 다중보기 및 저장된 프로 시저를 사용하여 액세스 방법을 제어한다면 어떨까요?

가장 일반적인 액세스 패턴에 대한보기를 만듭니다. 입력 날짜 매개 변수를 취할 수있는 쿼리를 처리

이제
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. 

코드 : 아마도 당신은 그들이 다음과 같을 수 2,008에서 2,010 사이에 대한 날짜 범위를 커버하는보기 2008-2009 2009-2010 등이 쿼리 할 뷰를 계산합니다. 예를 들어 :

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 

나는 아마 당신의 비즈니스 로직의 일부를 누락하고, 당신은 확실히 추가 할 것입니다 몇 가지 오류 처리 거기에 그것을 밖으로 쓰레기를 테스트하지만,이 비교적하기 쉬운입니다 작년 데이터를 보관할 새 데이터베이스를 만드는 것과 동시에 업데이트해야하는 유지 보수가 필요한 솔루션입니다.이 데이터는 일년에 한 번만 발생한다고합니다.

+0

영리한 +1!하지만 AL 테이블을 사용하는 모든 SP를 크게 변경해야합니다. 예를 들어, 현재 SQL은 IDASSET = 1 인 AL에서 select max (WHEN)와 같고 x와 y 사이의 [WHEN]은이 접근 방식으로 변환하기 위해 많은 작업이 필요합니다. 이것은 테이블 스칼라 UDF 접근법과 매우 비슷하지만 SP 내부에 래핑됩니다. – Nick

+0

글쎄, 나는 당신이 당신의 기존 질의에 아무런 효과가없는 마법의 총알을 발견 할 것이라고 확신하고 싶지만, 가능하지는 않을 것이라고 생각한다 - 당신은 동적 SQL을 사용할 수 없다. 보기 또는 기능. 오늘 MAX() 쿼리는 어떻게 작동합니까? –

+0

SP 실행 중 시간보기를 만드는 방법은 무엇입니까? UDF가 WHEN 값을 recivies하고 즉석에서 뷰를 생성하고 뷰 이름을 다시 소비하는 SP로 전송한다고하자. ??? ??? 보기를 끊임없이 생성하고 삭제할 때 성능이 저하됩니까? – Nick