4

varbinary(max) フィールドのオーディオ ファイルに blob FileStream を使用するようにセットアップされたデータベースがあります。それ以来、サイズが 80GB を超えて大きくなり、パフォーマンスの問題に直面しています。

いろいろ調べてみたところ、ブロブの平均サイズは約 180k であることがわかりました。また、MSDNによると、ファイル ストリームは 1 MB を超えるオブジェクトに使用する必要があるため、これらのブロブの保存方法を再評価しています。MSDN は、「小さいオブジェクトの場合、データベースに varbinary(max) BLOB を格納すると、多くの場合、ストリーミング パフォーマンスが向上します」と述べています。そのため、ファイルストリームを使用した varbinary(max) から varbinary(max) フィールドのみを使用するように移行することを検討しています。

私の質問は、SQL スクリプトを使用して各ファイルストリーム BLOB をファイルストリームから実際の varbinary フィールド自体に移動する優れた方法はありますか? 質問する前に私が取り組んできた別の方法は、ac# アプリでデータベースに BLOB をクエリさせ、各 BLOB をファイル システムに書き込むことです。次に、ファイルストリームのものをデータベースから手動で削除します。次に、C# アプリでファイル システムから BLOB を読み取り、データベースに書き戻します。もっと簡単な方法が必要だと思いました。

4

1 に答える 1

7

ソース テーブルが次のようになっているとします。

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

(2 番目のテーブルの列に FILESTREAM が欠落していることに注意してAudioDataください。これにより、バイナリ データが別の FILESTREAM ファイル グループではなく、残りのレコードと共にページ上に格納されます。)

次に、あるテーブルから別のテーブルにデータを挿入するだけです。

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

VARBINARY(MAX)または、元のテーブルの列のすぐ横に2 番目の列を作成しFILESTREAM、新しい列の値を古い列のデータで更新することもできます。どちらの方法でも、合計ディスク容量の使用量が 2 倍以上になることに注意してください。実際のオーディオ データの容量が 2 倍になり、FILESTREAM ファイル グループから PRIMARY ファイル グループ (またはメイン データ ファイルがある場所) に移行されます。トランザクション ログに多くのスペースがあります。

于 2012-08-31T16:41:46.403 に答える