2012-08-31 2 views
2

varbinary (max) 필드의 오디오 파일에 blob FileStream을 사용하도록 설정된 데이터베이스가 있습니다. 이후 80GB 이상의 크기로 성장했으며 성능 문제에 직면 해 있습니다.T-SQL에서 varbinary (max)를 파일 스트림으로 실제 varbinary (max)로 변환하는 방법

주위를 둘러 보았을 때 평균 블로 브 크기가 약 180k임을 발견했습니다. 그리고 1MB가 넘는 객체에는 MSDN 파일 스트림을 사용해야하므로이 BLOB를 어떻게 저장하는지 다시 평가할 것입니다. MSDN에서는 "더 작은 개체의 경우 데이터베이스에 varbinary (최대) BLOB를 저장하면 더 나은 스트리밍 성능을 제공하는 경우가 많습니다." 그래서 varbinary (max)에서 filestream로 옮기는 것을 고려하고 있습니다. varbinary (max) 필드를 사용하는 것뿐입니다.

내 질문은, 실제 varbinary 필드 자체로 filestream 각 filestream blob 이동하려면 SQL 스크립트를 사용하여 좋은 방법 있는가? 내가 묻기로 결정하기 전에 작업했던 대안은 blob을위한 데이터베이스를 쿼리하고 각 blob을 파일 시스템에 작성하는 것입니다. 그런 다음 수동으로 파일 스트림 항목을 데이터베이스에서 제거하십시오. 그런 다음 C# 응용 프로그램에서 파일 시스템의 blob을 읽고 데이터베이스에 다시 기록합니다. 나는 쉬운 방법이 있어야한다고 생각했다.

답변

5

은 소스 테이블을 가정하면 다음과 같습니다

CREATE TABLE audioFiles 
(
    AudioID INT IDENTITY NOT NULL PRIMARY KEY, 
    [Name] VARCHAR(50) NOT NULL, 
    [AudioData] VARBINARY(MAX) FILESTREAM NULL, 
    RowGuid UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL UNIQUE DEFAULT(NEWID()) 
) 

그런 다음 당신이 2 표 만들 수 있습니다

CREATE TABLE audioBlobs 
(
    AudioID INT IDENTITY NOT NULL PRIMARY KEY, 
    [Name] VARCHAR(50) NOT NULL, 
    [AudioData] VARBINARY(MAX) NULL, 
    RowGuid UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL UNIQUE DEFAULT(NEWID()) 
) 
GO 

(즉 FILESTREAM 두 번째 테이블의 AudioData 열에서 누락 된 참고를 .. 바이너리 데이터가 별도의 FILESTREAM 파일 그룹이 아닌 나머지 레코드와 함께 페이지에 저장되도록합니다.

ERT 한 테이블에서 다른 테이블의 데이터가 : 당신이 완료되면

SET IDENTITY_INSERT audioBlobs ON 

INSERT INTO audioBlobs (AudioID, Name, AudioData, RowGuid) 
    SELECT AudioID, Name, AudioData, RowGuid FROM audioFiles 

SET IDENTITY_INSERT audioBlobs OFF 

, 당신은 원래의 테이블을 삭제하고 원래 테이블의 이름으로 새 테이블의 이름을 바꿀 수 있습니다 :

DROP TABLE audioFiles 
GO 

EXECUTE sp_rename N'dbo.audioBlobs', N'audioFiles', 'OBJECT' 
GO 

또는, 원래 테이블의 FILESTREAM 열 바로 옆에 두 번째 VARBINARY(MAX) 열을 만들고 새 열의 값을 이전 열의 데이터로 업데이트하면됩니다. 두 가지 방법 중 하나를 선택하면 실제 오디오 데이터의 공간을 두 배로 늘리거나 FILESTREAM 파일 그룹에서 PRIMARY 파일 그룹 (또는 주 데이터 파일이있는 위치)으로 마이그레이션하고 디스크 공간 사용량을 두 배 이상 늘릴 수 있습니다. 트랜잭션 로그에 많은 공간이 있습니다.

+0

NEWID()는 인덱스에 적합하지 않습니다. 대신 NEWSEQUENTIALID()를 사용하십시오. –

관련 문제