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