Jam*_*oat 5 database-design sql-server
我们有一个数据库,它对数据中的大多数列使用 GUID(非顺序)。有没有人对 hgih 插入/更新数据库中 GUID 数据库的填充因子有任何最佳建议?
关于维护窗口,我们每晚都有停机时间,通常在周末关闭。
确实没有“理想的”填充因子,因为有太多其他因素需要考虑。
如果您有一个行大小为 3000 字节的表,那么您首先只能在数据页上容纳其中的 2 行。将 Fill Factor 设置为 50 最初会将页面构建为每个数据页只有 1 行,但这只会为添加一行留下空间。在高插入环境中,在该页面上发生页面拆分之前,这种情况真正持续多长时间?可能不会很长,即使由于使用 GUID 而“随机”放置也是如此。
唯一的“理想”这里是重建使用的表INT
或BIGINT
使用键字段IDENTITY
或SEQUENCE
。如果因为应用程序和/或客户知道它们而需要 GUID 值进行外部引用,那么在一个表中应该有它们的单个实例,并且该字段上应该有一个非聚集索引(这是已知的)作为备用键)。
这可能是一堆工作,不仅在脚本方面,而且在说服“业务”方面也可能是一项工作,可能还有一些应用程序代码更改,但考虑到聚集索引键被复制到所有非聚集索引中,PLUS PKs用于其他表的外键,所以现在表中有 FK 列带有 GUID,由于需要管理 16 字节值来查找事物而不是 4 或 8 字节值(分别为 INT 或 BIGINT),整个系统速度较慢。这意味着,即使在政治上困难重重,最终的结果也将是一个更快的系统,而人们很少抱怨这一点。
但是,如果您别无选择,只能保留 GUID PK,那么您别无选择,只能承受上述情况的后果(不幸的是)。
哦,关于使用NEWSEQUENTIALID()
这些帮助,因为它们不是碎片化的,但也不是完全连续的,因为每当 SQL Server NT 服务重新启动时,初始值都会重置,因此新值可能“低于”现有集。
并且,即使您每晚重建所有索引,您仍然会留下过大的键值(再次复制到非聚集索引中),这些值比/选项、PER EACH TABLE、PER EACH ROW多 2 到 4 倍的空间, 每个索引。净效应是从磁盘读取所有内容需要更长的时间,将内容写入磁盘需要更长的时间,所有操作占用更多内存(因为所有内容都通过缓冲池),备份需要更长的时间,恢复需要更长的时间,您可以保持更少的备份(每个相同的存储)等等。意思是:这不仅仅是一个理想主义的问题,就像关于哪种方法或事物更好的争论一样;如果您拥有除小型数据库之外的任何数据量,这些都是非常真实的后果。INT
BIGINT