【问题标题】:two duplicated indexes different sizes两个不同大小的重复索引
【发布时间】:2019-08-19 13:12:59
【问题描述】:

我有两个具有相同行数和相同列的重复索引,只有一个是 [22,488,980 行; 672.7MB],另一个是[22,488,980行; 3.9GB]

这怎么可能?

索引的列如下: 索引 1:

[3 KEYS] user_hour_log_user_id {int 4},user_hour_log_out_type_id {tinyint 1},user_hour_log_id {bigint 8} [1 INCLUDE] user_hour_log_out_time {datetime 8}

读取:764,131,409(764,131,409 次查找)写入:3,051,570

22,488,980 行; 672.7MB

索引 2:

[3 KEYS] user_hour_log_user_id {int 4},user_hour_log_out_type_id {tinyint 1},user_hour_log_id {bigint 8}

读取:0 写入:3,051,570

22,488,980 行; 3.9GB

我使用过 Brent Ozar 的 sp_BlitzIndex

【问题讨论】:

标签: sql sql-server indexing


【解决方案1】:

正如在另一个答案中所评论的,问题在于第二个索引中的 FILLFACTOR 选项设置为 10。

FILLFACTOR=10 意味着只有 10% 的页面文件将被填充,而 FILLFACTOR=95 意味着 95% 的页面将被填充。

FILLFACTOR=10 选项意味着您的索引将使用它所需的 10 倍以上的页面(因此,大小)。一个数据页文件为 8KB。 8KB 的 10% 是 800B。第二个索引的一行数据为 4+1+8 = 13B,因此引擎可以在每个数据页文件中写入 63 行。在第一个索引上,它使用了 8KB 的 95%,即 7600B。一行是4+1+8+8 = 21。引擎可以写361行/页,是63行的5.7倍。这个比例大致相当于3900MB/672MB,即两个索引大小的比例。

在任何情况下,我都不建议填充因子为 10。

想象一个书架。索引就像书架:您按字母顺序存储书籍(行)。 FILLFACTOR=100 表示当您整理(重建)书架时,您不会在任何书架的行(数据页)中留下任何空间。

FILLFACTOR=90 表示您留下 10% 的行空间(数据页文件的 10%)。

FILLFACTOR=10 表示您留下了 90% 的剩余空间。

现在,为什么这对我们有帮助?好吧,如果你在书架上获得了新书(插入新行),如果你在行上还有一些空间,你可以在不移动其他行中的任何其他书的情况下插入这本书。如果您的 FILLFACTOR=100,那么运气不好,您需要为您的书腾出空间,并在上一行或下一行移动其他书。

这称为PAGE SPLITTING and has a performance impact,因为这会产生额外的 IO。这就是为什么建议减少您知道会经常修改的索引的填充因子,以减少页面拆分的数量。

您可以在此处阅读 Brent Ozar 的论文以获取有关填充因子选项的更多建议:

https://www.brentozar.com/blitz/fill-factor/

干杯。

【讨论】:

  • 我只是添加了一条评论,建议您将评论发布到 Gordon 的答案中作为答案。 +1
  • 别忘了你需要to rebuild that index
【解决方案2】:

如果这些索引是同一张表上的相同列,那么您可能正在目睹索引碎片的作用。有很多资源对此进行了详细描述(例如this one)。在这里,我只想让您了解正在发生的事情。

当您在表上创建索引时,应该非常高效地构建它——正是表所需的数据结构。

但是,当您启动 inserting、deleteing 和 updateing 记录时,索引会发生变化。特别是,值不是添加在索引的末尾,而是“在中间”。需要找到新的空间,因此现有的索引页面被分成两个部分填充的页面。此过程会导致索引碎片化。

所以,如果您在一个空表上定义了一个索引,然后插入了行,那么您可能有一个碎片索引。如果您在填充表后在相同列上创建索引,它将是一个简洁、高效的索引。

【讨论】:

  • 可能不是碎片,昨晚都重建了,有include的一个是8%,另一个没有include列的不到1%。但我确实注意到较小的索引具有 FILLFACTOR=95 而另一个具有 FILLFACTOR=10。这是大小不一的原因吗?
  • FILLFACTOR=10 是精神错乱。 @katinovikov 为什么会选择这个?将其更改为 100。:)_
  • @katinovikov 没错。 FILLFACTOR=10 意味着只有 10% 的页面文件将被填充,而 FILLFACTOR=95 意味着 95% 的页面将被填充。 FILLFACTOR=10 选项意味着您的索引将使用它需要的 10 倍以上的页面(因此,大小)。请记住,数据页文件为 8KB。 8KB 的 10% 是 800B。你的第二个索引的一行数据是 4+1+8 = 13B。您将能够为每个数据页文件写入 63 行。在您的第一个索引上,您使用了 8KB 的 95%,即 7600B。一行是 4+1+8+8 = 21。可以写 361 行/页,是 63 行的 5.7 倍。这个比例与 3900MB/672MB 大致相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多