我在将数据库存储到数据库时遇到了一些问题。我们目前有大约40万条记录,但我预计这会很快增加到数百万条。目前我已经遇到了性能问题,所以这是一个主要问题。我在决定使用SQL Server存储图像之前做了一些研究,我读到的所有内容都表明它能够做到这一点。
我设计的表非常简单,包含3列......
逻辑是我在我的应用程序代码中生成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插件(从实体框架生成)。这是二进制语句,但我已将其中的大部分截断为......这是在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...
所以我的问题是......
提前感谢您的时间!
答案 0 :(得分:2)
因为您的索引(包括主键上的聚簇索引)位于uniqueidentifier上,所以这些索引将非常快速地分段。
禁用短文件名(8.3)生成 当长文件名是 使用Windows NTFS文件系统创建,默认行为是 在旧的8.3 DOS文件中生成相应的短文件名 与旧操作系统兼容的名称约定。这个 可以通过注册表项禁用功能,提供 性能提升。
fsutil behavior set disable8dot3 1
禁用NTFS上次访问更新 NTFS上的每个文件和文件夹 volume包含一个名为Last Access Time的属性。这个属性 显示上次访问文件或文件夹的时间,例如用户时 执行文件夹列表,将文件添加到文件夹,读取文件或 对文件进行更改。维护此信息会产生 文件系统的性能开销,尤其是在环境中 快速访问大量文件和目录的地方 在很短的时间内,例如使用BizTalk文件时 适配器。除了在高度安全的环境中,保留这一点 信息可能会增加服务器的负担,可以避免 更新以下注册表项:
fsutil行为设置disablelastaccess 1
答案 1 :(得分:0)
你需要做尽职调查并收集至少一些最小的信息,因为这是任何人猜测问题是什么。您需要做的第一件事是阅读Waits and Queues以熟悉用于排除SQL Server性能问题的正确调查技术,并应用该方法来收集相关信息。
现在我的观点是基于没有任何证据的。您的INSERT可能会阻塞,我们无法知道原因。使用Activity Monitor了解阻止INSERT的内容。这不是由碎片造成的(永恒的red herring)。如果我冒昧地猜测,罪魁祸首是使用默认范围新的System.Transactions和awful serialization isolation this brings。
作为旁注:UNIQUEIDENTIFIER
是散列的可怕数据类型选择。要生成与图像有某种关联的哈希,您必须运行哈希算法,如MD5或SHA。您可能正在使用MD5并生成16字节密钥,但绝对没有理由将其存储为16字节长度UNIQEUIDENTIFIER
类型。使用BINARY(16)
。如果你想在将来转移到SHA1(20字节散列)或其他散列,也要考虑。