【发布时间】:2018-04-05 11:22:08
【问题描述】:
我有一个表,它有 124,387,133 行,每行有 59 列,在这 59 列中,有 18 列是 TinyInt 数据类型,所有行值都是 0 或 1。一些 TinyInt 列用于索引,一些不是。
如果我将 tinyint 更改为一点,我的问题是否会对查询性能和表大小产生影响?
【问题讨论】:
标签: sql sql-server sql-server-2012 database-administration tinyint
我有一个表,它有 124,387,133 行,每行有 59 列,在这 59 列中,有 18 列是 TinyInt 数据类型,所有行值都是 0 或 1。一些 TinyInt 列用于索引,一些不是。
如果我将 tinyint 更改为一点,我的问题是否会对查询性能和表大小产生影响?
【问题讨论】:
标签: sql sql-server sql-server-2012 database-administration tinyint
每条记录将节省大约 15 个字节,总共 1.8 GB。
您还有 41 个字段。如果我假设这些是 4 字节整数,那么您当前的总大小约为 22 GB。总体节省不到 10% - 如果其他字段更大,可能会少得多。
这确实意味着全表扫描会快 10% 左右,因此您可以了解性能提升和幅度。
我相信位字段需要一两个额外的操作来屏蔽位和读取 - 这些天以纳秒为单位测量的微不足道的开销 - 但要记住一些事情。
较小的页面大小的好处是在一个页面上可以容纳更多的记录,因此该表在内存中占用的空间更少(假设一次全部读入)和更少的磁盘空间。较小的数据并不总是意味着提高查询性能。这里有两个警告:
对于删除和更新等其他操作,有时会在页面级别进行锁定。在这些情况下,稀疏页面可以带来更好的性能。
【讨论】:
理论上是的,实际上差异会很微妙,18 位字段被字节打包并四舍五入,所以它变成了 3 个字节。根据可空性/任何可空性更改,存储成本将再次发生变化。两种类型都保持在行的固定宽度部分内。因此,对于这些字段,您将从 18 个字节减少到 3 个字节 - 根据行的整体大小与页面大小,您可能会在页面上挤压额外的行。 (行/页面密度是性能提升主要体现的地方,如果你想获得的话)
这似乎是一种过早的微优化,但是,如果您的性能不佳,请进行调查并收集支持任何更改的证据。应该仔细考虑对现有系统进行类型更改,如果您需要更改代码,这会提示进行完整的回归测试等,更改的成本会急剧上升 - 最终结果很少。 (大型数据集的生产更改也不会很快,因此您可以在成本中考虑一些停机时间来进行更改)
【讨论】:
实际上,使用正确的数据类型是件好事。以下是我在使用位数据类型时可以看到的好处
1.缓冲池节省,页面从存储中读入内存,可以分配更少的内存
2.索引键的大小会更小,因此一页可以容纳更多的行,并且可以减少遍历
您还可以看到节省存储空间的直接好处
【讨论】:
如果您不知道,与 TinyInt(1 位对 8 位)相比,bit 使用更少的空间来存储信息。所以你会节省空间改为位,理论上性能应该更好。通常很难注意到这样的性能改进,但是根据您拥有的数据量,它实际上可能会有所作为,我会在备份副本中对其进行测试。
【讨论】: