我需要在SQL 2012数据库中记录应用程序事件。基本的记录结构要求非常简单:
CREATE TABLE [dbo].[EventLog]
(
[ProcessId] INT NOT NULL,
[ApplicationId] INT NOT NULL,
[Created] DateTime NOT NULL,
CONSTRAINT [PK_EventLog] PRIMARY KEY CLUSTERED ([ProcessId],[ApplicaionId],[Created] ASC)
)
我遇到的问题是性能问题。每天最多可生成100万个事件,随着行数的增加,插入性能也会下降 - 直到记录器无法跟上事件的程度。
我已经将批量日志写入中间纯文本文件,然后使用与主应用程序记录器分开运行的服务处理这些文件。
我怀疑罪魁祸首可能是维持索引,我想就如何更有效/更有效地解决这个问题提出一些建议。
非常感谢任何建议。
答案 0 :(得分:1)
性能问题的主要原因可能是选择形成聚簇索引的列。
在聚簇索引中,数据实际上按索引键列定义的顺序存储在索引的叶级页面中。因此,在您的表中,数据以ProcessID, ApplicationID, Created
的顺序存储。
在没有看到您的数据的情况下,我会假设随着时间的推移,各种ProcessID
和ApplicationID
都会创建日志条目。如果是这种情况,对于每个插入,SQL实际上将在日志表中间的适当位置插入每个日志条目。对于SQL Server而言,这比在表的末尾插入记录更耗时。此外,当插入的记录无法放入适当的页面时,将发生页面拆分,这将导致聚簇索引碎片化 - 这将进一步降低性能。
理想情况下,您的目标应该是拥有尽可能小的聚类键,同时也是唯一的。因此,一种方法是创建一个新的ID列作为标识,并在其上创建聚簇索引。例如:
CREATE TABLE [dbo].[EventLog]
(
[EventLogId] INT IDENTITY(1,1),
[ProcessId] INT NOT NULL,
[ApplicationId] INT NOT NULL,
[Created] DateTime NOT NULL,
CONSTRAINT [PK_EventLog] PRIMARY KEY CLUSTERED ([EventLogId])
)