我有一个包含 3000 万行的数据库。PK 聚集索引是一个代码生成的GUID
。
表格如下:
CREATE TABLE [dbo].[events](
[imageEventGUID] [uniqueidentifier] NOT NULL,
[imageSHAID] [nvarchar](256) NOT NULL,
[queryGUID] [uniqueidentifier] NOT NULL,
[eventType] [int] NOT NULL,
[eventValue] [nvarchar](2050) NULL,
[dateOfEvent] [datetime] NOT NULL,
CONSTRAINT [PK_store_image_event] PRIMARY KEY CLUSTERED
(
[imageEventGUID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
简单地说,它是一个图像搜索引擎。
imageEventGUID
是代码唯一标识符,imageSHAID
是图片 URL 的 SHA256queryGUID
是代码生成的 FK(为简洁起见,从 create 语句中排除)eventType
是分配给它是什么类型的事件的数字eventValue
通常是图像的 URI,例如“ http://mywebpage.com/images/image123456789.jpg ”
我定期使用非常标准的代码将 via SqlBulkCopy
(from a DataTable
) 插入到此表中:
using (SqlBulkCopy bulk = new SqlBulkCopy(storeConn, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.KeepNulls, null))
{
bulk.DestinationTableName = "[dbo].[events]";
bulk.WriteToServer(myeventsDataTable);
}
我通常尝试在一次批量插入中插入 5k 到 10k 行。我从这个批量复制中得到了糟糕的插入结果。我曾经在 SSD 上运行这个数据库(只连接了 SATA 1),而且速度非常快(不到 500 毫秒)。我的 SSD 空间不足,所以我将 DB 换成了 1TB 7200 高速缓存旋转磁盘,此后完成时间超过 120 秒(120000 MS)。当批量插入运行时,我可以看到大约 1MB/秒的磁盘活动,CPU 使用率很低。
除了 PK,我在这个表上没有其他索引。
我对你的问题是:
你能看到任何明显的我做错的事情会导致这种情况吗?
这只是“您的旋转磁盘对于这种大小的数据库来说不够快”的情况吗?
插入此数据时到底发生了什么?因为它是聚集索引,所以在插入时它会重新排列磁盘上的数据页吗?它正在尝试插入本质上是无序的 GUIDS,因此这种“随机插入性质”可能导致读/写标题在磁盘上的不同页面上移动很多?
谢谢你的时间。