SQL Server性能:50列vs单二进制/ varbinary

Lou*_*Lou 3 sql-server performance blob denormalization varbinary

是否可以通过用float一个binary(n)(n50 x 4)替换(比如说)50 列来改进SQL Server 2008 R2(和更新版本)的插入性能?

认为使用固定大小binary(n)应该可以提高性能(数据量相同,处理所有列和更短的SQL查询所需的工作量更少),但许多网站建议不要使用binary列,所以我想看看是否有使用它真的有问题吗?

此外,问题是该表是非规范化的,并且通常不是所有列都填充值,因此varbinary(n)在许多情况下允许我减小行大小.有时只填充一列,但平均为~10列.

然后第三个问题是,如何更进一步,用一个替换(比如说)5行×50 float32varbinary(5*50*4)

因此,获得一些见解会很酷:

  1. float用单个替换1行50 列binary(200);
  2. float用单个替换1行50 x varbinary(204)(标志/长度信息的几个字节) - 在未使用列时节省空间;
  3. float用单个替换5行50 x varbinary(1024)(标志/长度信息的几个字节).

在所有情况下,始终一次读取整行.

(更新)

为了澄清,存储的数据是:

 Timestamp_rounded    Value_0ms  Value_20ms  Value_40ms ... Value_980ms
 2016-01-10 10:00:00    10.0       11.1        10.5     ...    10.5
Run Code Online (Sandbox Code Playgroud)

我总是读取整行,主要聚类键是第一列(Timestamp),我将永远不必通过任何其他列查询表.

标准化数据显然会有一个Timestamp/ Value对,Timestamp然后具有毫秒精度.但是我必须存储50行的两列,而不是1行(Timestamp+ BLOB).

Rem*_*anu 5

这是个主意.拥有50列4个字节而不是一个200字节的列消除了为这50个列中的任何一个优化查询的任何希望.首先,从"经典"SQL Server pov开始:

  • 您可以消除下推谓词和扫描时间过滤
  • 您消除了索引的可能性
  • 您消除了数据纯度检查(对于浮点数尤其重要,因为并非所有位模式都可以生成有效的浮点数!)
  • 您可以消除基于成本优化的列统计信息

当你更"现代"并开始考虑SQL Server更新的选项时:

所有这些甚至没有考虑到你对试图查询数据的同胞造成的痛苦.

问题是该表是非规范化的,并且并非所有列都通常填充值,因此varbinary(n)允许我在许多情况下减小行大小.有时只填充一列,但平均为~10列.

然后使用行压缩存储:

ALTER TABLE <your table> REBUILD PARTITION = ALL  
   WITH (DATA_COMPRESSION = ROW);
Run Code Online (Sandbox Code Playgroud)

如果数据仅附加且很少更新/删除,并且大多数查询都是分析性的,那么甚至可以更好地使用列存储.由于SQL Server 2016 SP1列存储可用于每个 SQL Server版本.


Pet*_*ell 2

作为实验,我尝试了两种不同的方法来比较它们。

我发现经过一些调整后,二进制版本比 50 col 版本快大约 3 倍。

这个场景非常具体,我的测试只测试了非常具体的东西。任何与我的测试设置的偏差都会对结果产生影响。

测试是如何进行的

对于 50 col 版本,我有 50 个可为空的浮点列,我将它们全部填充为float.MaxValue.

对于二进制版本,我只有一列。该列的值由 50x 的字符串构造而成float.MaxValue + "|",全部连接成一个长字符串。然后将该字符串转换为 byte[] 以存储在表中。

两个表都是没有索引或约束的堆。

我的测试代码可以在这里找到https://github.com/PeterHenell/binaryBulkInsertComparison

我在带有 SSD 驱动器的 6 核工作站上的 SQL Server 2014 Developer Edition 上运行了测试。