许多应用程序将日志记录信息存储在日志表中。
这些表很特殊,因为您只会执行插入操作。你永远不会进行更新。如果您确实进行了删除,那么清除旧数据将是一项每晚的工作。
该表有一个日期时间字段,该字段通常严格递增。调用应用程序可能会失去与数据库的连接,并且会堆积插入,并且在它获得连接时,它不能保证它将按照严格的顺序执行插入。但总的来说,如果日期时间字段是聚集索引,我预计在插入时对表进行排序会很便宜。
大多数查询将查询日期时间,但这些将是不等式查询。
有了这些特殊的属性,感觉应该有一种方法来优化它。
最佳实践是什么?
日志表的示例可以是:
CREATE TABLE logMessages (
logTime datetime2(6) NOT NULL,
logSeverity varchar(10) NOT NULL,
logStatus varchar(10) NOT NULL,
logText varchar(255),
processID bigint,
processUser varchar(25)
)
Run Code Online (Sandbox Code Playgroud)
一个典型的查询:
SELECT logTime, logSeverity, logText
FROM logMessages
WHERE logTime >= '2020-10-01'
AND logTime < '2021-11-01'
AND logSeverity IN ('WARNING','ERROR','FATAL')
Run Code Online (Sandbox Code Playgroud)
唯一身份?
日期时间字段不唯一,我们是否需要唯一标识符?
选项 1:添加logId BIGINT IDENTITY列
如果我们添加一个唯一的 logId,它将不会在任何其他表中用作外键。
如果我们单独使用它作为聚集索引,并且 SQL Server 认为我们的查询将检索太多行而无法使用非聚集索引,那么它将执行全表扫描。
将聚集索引设置为 (logTime, logId) 是否有意义?我想要这样做的原因是,当查询优化器不会在 logTime 上使用非聚集索引时,因为它需要太多行,那么依靠良好的聚集索引将减少要扫描的行数。
选项 2:不添加 logId
将聚集索引设置为 (logTime)。由于 logTime 不是唯一的,SQL Server 必须通过添加不可见列来使其唯一。这是一个问题吗?至少我得到了一个良好的聚集索引,这将有助于我的大多数查询。
查找表
logSeverity …