sql-server - 在日志表上不断增加的日期时间列上聚集索引?

标签 sql-server indexing

我不是 DBA(“好!”,您很快就会想到。)

我有一个记录数据的表,其中包含这些特征和使用模式:

  • datetime 列,用于存储日志时间戳,其值不断增加且大部分(但仅大部分)是唯一的
  • 仅在时间戳范围末尾(记录新数据)进行频繁插入(例如,每分钟十几个)
  • 从时间戳范围的开头开始不频繁地批量删除(旧数据被清除)
  • 根本没有更新
  • 频繁选择使用时间戳列作为主要标准,以及其他列的次要标准
  • 不频繁选择使用其他列作为条件(并且包括时间戳列)
  • 数据量很大,但还远远不够,以至于我非常担心存储空间

此外,目前有一个每日维护窗口,在此期间我可以进行表优化。

坦率地说,即使我对它建立了一点错误索引,我也不认为该表会对它所在的服务器构成挑战,但尽管如此,这似乎是一个询问有关 SQL Server 聚集索引的一些信息的好机会。

我知道聚集索引决定了实际表数据的存储(数据存储在索引本身的叶节点中),而非聚集索引是指向数据的单独指针。因此,在查询方面,聚集索引将比非聚集索引更快——一旦我们找到索引值,数据就在那里。插入和删除都会产生成本(当然,更改聚集索引列的值的更新成本会特别高)。

但我读过in this answer删除留下的间隙,除非重建索引,否则这些间隙不会被清理。

所有这些都表明我应该:

  • 在时间戳列上放置一个填充因子为 100% 的聚集索引
  • 将非聚集索引放在任何其他列上,这些列可用作查询中的条件,但不涉及聚集列(在我的情况下可能是其中的任何列)
  • 安排在每日维护间隔期间进行批量删除
  • 安排在批量删除后立即重建聚集索引
  • 放松心情,多出去走走

我是不是太离谱了?我是否需要像这样频繁地重建索引以避免大量空间浪费?还有其他明显的(对于 DBA 来说)我应该做的事情吗?

提前致谢。

最佳答案

与许多人认为的相反,在表上拥有良好的聚集索引实际上可以使 INSERT 等操作更快 - 是的,更快!

查看开创性的博客文章 The Clustered Index Debate Continues....作者:Kimberly Tripp - 终极索引女王。

她提到(大约在文章中间):

Inserts are faster in a clustered table (but only in the "right" clustered table) than compared to a heap. The primary problem here is that lookups in the IAM/PFS to determine the insert location in a heap are slower than in a clustered table (where insert location is known, defined by the clustered key). Inserts are faster when inserted into a table where order is defined (CL) and where that order is ever-increasing.

关键点是:只有使用正确的聚集索引,您才能获得好处 - 当聚集索引是唯一的、狭窄的、稳定的并且最佳地不断增加时。最好使用 INT IDENTITY 列来实现这一点。

Kimberly Tripp 还有一篇很棒的文章,介绍如何为表选择最佳的聚类键,以及它应该满足什么标准 - 请参阅她的文章,标题为 Ever-increasing clustering key - the Clustered Index Debate..........again!

如果您有这样的专栏 - 例如代理主键 - 将其用作集群键,您应该会在表上看到非常好的性能 - 即使在大量 INSERT 上也是如此。

关于sql-server - 在日志表上不断增加的日期时间列上聚集索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2217746/

相关文章:

angularjs - 是否可以用日期索引 Angularjs 中的表?

python - 如何获取 Pandas Dataframe 中特定列值之后的 n 行之前或之后

sql - 在 SQL Server 中按多列分组

sql-server - 我真的需要使用 "SET XACT_ABORT ON"吗?

excel - 索引-与垂直和水平标准匹配

javascript - 示例 jquery 获取 sibling 的索引/位置

python - 多索引失败

sql - 获取每月活跃员工数量的最佳方法是什么?

sql-server - 列出 SQL Server 数据库中的表名、所有者、架构和列

c# - Linq选择项目,它等于另一个表中的ID