James Rhoat Asked: 2016-04-21 12:36:26 +0800 CST2016-04-21 12:36:26 +0800 CST 2016-04-21 12:36:26 +0800 CST GUID 聚类键的最佳填充因子 772 我们有一个数据库,它对数据中的大多数列使用 GUID(非顺序)。是否有人对 hgih 插入/更新数据库中 GUID 数据库的填充因子有任何最佳建议? 关于维护窗口,我们每晚都有停机时间,通常在周末关闭。 sql-server database-design 2 个回答 Voted Best Answer Solomon Rutzky 2016-04-21T12:52:33+08:002016-04-21T12:52:33+08:00 确实没有“理想的”填充因子,因为要考虑的其他因素太多了。 表的实际页面大小是多少? 表中有多少可变长度列?如果不是“无”,那么:可变长度字段更新为大于其初始值的长度的可能性/频率有多大? 如果您有一个行大小为 3000 字节的表,那么您首先只能在数据页上放置其中的 2 行。将填充因子设置为 50 最初会将页面构建为每个数据页只有 1 行,但这只会为添加一行留出空间。在高插入环境中,在该页面上发生页面拆分之前,这真正持续了多长时间?可能不会很长,即使由于使用 GUID 而出现“随机”展示位置。 这里唯一的“理想”是使用 or 使用orINT键BIGINT字段重建表。如果您需要用于外部引用的 GUID 值,因为它们为应用程序和/或客户所知,那么在一个表中应该有它们的单个实例,并且该字段上应该有一个非聚集索引(这是已知的作为备用键)。IDENTITYSEQUENCE 这可能是一堆工作,不仅在脚本方面,还可能在说服“业务”方面,可能还有一些应用程序代码更改,但考虑到聚集索引键被复制到所有非聚集索引中,PLUS PK用于其他表的外键,因此现在在具有 GUID 的表中存在 FK 列,由于需要管理 16 字节值而不是 4 或 8 字节值(分别为 INT 或 BIGINT)来查找内容,整个系统速度较慢。这意味着,即使在政治上很困难,最终的结果将是一个更快的系统,人们很少抱怨这一点。 但是,如果您别无选择,只能保留 GUID PK,那么您别无选择,只能承受上述情况的后果(不幸的是)。 哦,关于使用NEWSEQUENTIALID()这些帮助,因为它们不是碎片化的,但也不是完全连续的,因为每当重新启动 SQL Server NT 服务时初始值都会重置,因此新值可能“低于”现有集。 而且,即使您每晚重建所有索引,您仍然会留下过大的键值(再次复制到非聚集索引中),它们占用的空间比/选项、每个表、每行多 2 到 4 倍, 每个索引。最终结果是从磁盘读取所有内容需要更长的时间,将内容写入磁盘需要更长的时间,所有操作占用更多内存(因为所有内容都通过缓冲池),备份需要更长的时间,恢复需要更长的时间,你可以保留更少的备份(每个相同的存储)等 如果您有任何数据量而不是小型数据库,这些都是非常真实的后果。INTBIGINT Arthur D 2016-04-21T12:43:09+08:002016-04-21T12:43:09+08:00 注意事项: 你能负担多少磁盘空间/内存?较低的填充因子将意味着较大的索引。 您能否衡量当前的性能影响并根据页面预期寿命和页面拆分进行调整?(像 Ola Hallengren 的脚本这样的维护解决方案将提供一个记录重建操作的表) 请记住,即使更新模式是零星的,较低的填充因子也会以页面预期寿命为代价,因为它将需要更多的内存页面才能将相同数量的结果返回给应用程序。 这些是聚集索引键,还是仅用于非聚集索引?
确实没有“理想的”填充因子,因为要考虑的其他因素太多了。
如果您有一个行大小为 3000 字节的表,那么您首先只能在数据页上放置其中的 2 行。将填充因子设置为 50 最初会将页面构建为每个数据页只有 1 行,但这只会为添加一行留出空间。在高插入环境中,在该页面上发生页面拆分之前,这真正持续了多长时间?可能不会很长,即使由于使用 GUID 而出现“随机”展示位置。
这里唯一的“理想”是使用 or 使用or
INT
键BIGINT
字段重建表。如果您需要用于外部引用的 GUID 值,因为它们为应用程序和/或客户所知,那么在一个表中应该有它们的单个实例,并且该字段上应该有一个非聚集索引(这是已知的作为备用键)。IDENTITY
SEQUENCE
这可能是一堆工作,不仅在脚本方面,还可能在说服“业务”方面,可能还有一些应用程序代码更改,但考虑到聚集索引键被复制到所有非聚集索引中,PLUS PK用于其他表的外键,因此现在在具有 GUID 的表中存在 FK 列,由于需要管理 16 字节值而不是 4 或 8 字节值(分别为 INT 或 BIGINT)来查找内容,整个系统速度较慢。这意味着,即使在政治上很困难,最终的结果将是一个更快的系统,人们很少抱怨这一点。
但是,如果您别无选择,只能保留 GUID PK,那么您别无选择,只能承受上述情况的后果(不幸的是)。
哦,关于使用
NEWSEQUENTIALID()
这些帮助,因为它们不是碎片化的,但也不是完全连续的,因为每当重新启动 SQL Server NT 服务时初始值都会重置,因此新值可能“低于”现有集。而且,即使您每晚重建所有索引,您仍然会留下过大的键值(再次复制到非聚集索引中),它们占用的空间比/选项、每个表、每行多 2 到 4 倍, 每个索引。最终结果是从磁盘读取所有内容需要更长的时间,将内容写入磁盘需要更长的时间,所有操作占用更多内存(因为所有内容都通过缓冲池),备份需要更长的时间,恢复需要更长的时间,你可以保留更少的备份(每个相同的存储)等 如果您有任何数据量而不是小型数据库,这些都是非常真实的后果。
INT
BIGINT
注意事项:
请记住,即使更新模式是零星的,较低的填充因子也会以页面预期寿命为代价,因为它将需要更多的内存页面才能将相同数量的结果返回给应用程序。
这些是聚集索引键,还是仅用于非聚集索引?