0

データベースに画像を保存する際に問題が発生しています。現在、約 40 万件のレコードがありますが、これが急速に数百万件に増加すると予想しています。現時点では、パフォーマンスの問題がすでに発生しているため、これは大きな懸念事項です。SQL Server を使用して画像を保存することを決定する前に、少し調査を行いましたが、読んだすべてのことから、SQL Server がこれを実行できることが示されました。

私はテーブルを3つの列を含む非常にシンプルになるように設計しました...

  • Id (主キー、一意の識別子、null 以外)
  • ImageHash (一意の識別子、null 以外)
  • BinaryImage (varbinary(max)、null 以外)

ロジックは、アプリケーション コードで ImageHash を生成することでした。イメージ ハッシュは、バイナリ イメージがデータベースに既に存在するかどうかを確認するための挿入前のルックアップに使用されます。残りの時間は、ID を直接使用してテーブルをクエリするだけです。

.NET Entity Framework を使用してデータ アクセスを実行しています。Id 列は挿入時に生成されていますが、それがベスト プラクティスであるかどうかはわかりません。

これが私のテーブルの作成スクリプトです。ImageHash のインデックスを作成しましたが、SQL Server インデックスについてよく理解していません。

CREATE TABLE [dbo].[ImageContent](
    [Id] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
    [ImageHash] [uniqueidentifier] NOT NULL,
    [BinaryImage] [varbinary](max) NOT NULL,
 CONSTRAINT [PK_ImageData] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = ON, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

ALTER TABLE [dbo].[ImageContent] ADD  CONSTRAINT [DF_ImageData_Id]  DEFAULT (newid()) FOR [Id]

そしてインデックス…。

CREATE NONCLUSTERED INDEX [ImageHash_Index] ON [dbo].[ImageContent]
(
    [ImageHash] ASC
)
INCLUDE (   [Id]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

すべてのインデックスを再構築しましたが、問題は解決していません。私はSQL Server Profilerをいじっていて、問題の原因となっているSQL Insertを特定しました(Entity Frameworkから生成されました)。これはバイナリのステートメントですが、その大部分を切り捨てました...これは30秒後にタイムアウトしました...

exec sp_executesql N'declare @generated_keys table([Id] uniqueidentifier)
insert [dbo].[ImageContent]([ImageHash], [BinaryImage])
output inserted.[Id] into @generated_keys
values (@0, @1)
select t.[Id]
from @generated_keys as g join [dbo].[ImageContent] as t on g.[Id] = t.[Id]
where @@ROWCOUNT > 0',N'@0 uniqueidentifier,@1 varbinary(max) ',@0='DF76D1FF-5C05-58E0-0933-1ADBCC6345A8',@1=0xFFD8FFE1214545786966000049492A00080000000D00000103...

だから私の質問は...

  • 私がこれを設定した方法で、誰かがいくつかの大きな問題を見ることができますか?
  • パフォーマンスを改善するのに役立つ推奨事項はありますか?
  • SQL Server は、この方法で何百万もの画像を保存できますか?

お時間をいただきありがとうございます。

4

2 に答える 2

2

インデックス (主キーのクラスター化インデックスを含む) は一意の識別子に基づいているため、これらのインデックスはすぐに断片化されます。

  1. 正当な理由がない限り、ID として単調に増加する INT/BIGINT IDENTITY を検討してください。
  2. NCI(ImageHash_Index)のフィルファクターを調整し、定期的に再編成/再構築するジョブがあることを確認してください
  3. 実際の画像が 2 MB を超える場合は、FILESTREAM を使用して実際の画像を保存することを検討してください。ここにホワイトペーパーがあります: http://msdn.microsoft.com/library/hh461480。この方法を使用する場合、他に 2 つのパフォーマンスに関する考慮事項があります。それらに関する情報はこちら: http://msdn.microsoft.com/en-us/library/ee377058(v=bts.10).aspx .

短いファイル名 (8.3) の生成を無効にする Windows NTFS ファイル システムを使用して長いファイル名が作成される場合、既定の動作では、古いオペレーティング システムとの互換性のために、古い 8.3 DOS ファイル名規則で対応する短いファイル名が生成されます。この機能は、レジストリ エントリを使用して無効にすることができ、パフォーマンスが向上します。

fsutil 動作セット disable8dot3 1

NTFS の最終アクセス更新を無効にする NTFS ボリューム上の各ファイルとフォルダには、最終アクセス時刻と呼ばれる属性が含まれています。この属性は、ユーザーがフォルダーの一覧表示を実行したとき、フォルダーにファイルを追加したとき、ファイルを読み取ったとき、またはファイルに変更を加えたときなど、ファイルまたはフォルダーが最後にアクセスされたときを示します。この情報を維持すると、ファイル システムのパフォーマンス オーバーヘッドが発生します。特に、BizTalk ファイル アダプターを使用する場合など、多数のファイルとディレクトリに短時間ですばやくアクセスする環境では顕著です。非常に安全な環境以外では、この情報を保持するとサーバーに負担がかかる可能性があります。これは、次のレジストリ キーを更新することで回避できます。

fsutil 動作セット disablelastaccess 1

于 2013-07-30T02:07:56.127 に答える