是否可以通过用float
(binary(n)
为50 x 4)替换(例如)50 n
列来改进SQL Server 2008 R2(和更新版本)插入性能?
我推测使用固定大小binary(n)
可以提高性能(数据量相同,处理所有列和更短的SQL查询所需的工作量更少),但是许多网站建议不要使用binary
列,因此我想看看使用它是否确实存在问题?
此外,问题是该表是非规范化的,并且并非所有列通常都填充了值,因此varbinary(n)
允许我在许多情况下减小行大小。有时只填充一列,但平均为~10。
然后第三个问题是,如何更进一步,用一个float32
替换(比方说)5行x 50 varbinary(5*50*4)
列?
因此,获得一些见解会很酷:
float
; binary(200)
列
float
替换1行50 x varbinary(204)
(标志/长度信息的几个字节) - 在未使用列时节省空间; 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
我总是在读取整行,主要聚类键是第一列(Timestamp),我将永远不必通过任何其他列查询表。
标准化数据显然会有Timestamp
/ Value
对,其中Timestamp
将具有毫秒精度。但是,我必须存储50行的两列,而不是1行(Timestamp
+ BLOB
)。
答案 0 :(得分:5)
这是一个糟糕的想法。拥有50列4个字节而不是一个200字节的列消除了为这50个列中的任何一个优化查询的任何希望。首先,从“经典”SQL Server pov:
开始随着你越来越'现代'并开始考虑SQL Server更新的选项:
所有这些甚至都没有考虑到你试图查询数据的同胞所造成的痛苦。
问题是该表是非规范化的,并且并非所有列都通常填充值,因此varbinary(n)允许我在许多情况下减小行大小。有时只填充一列,但平均为~10。
然后使用行压缩存储:
ALTER TABLE <your table> REBUILD PARTITION = ALL
WITH (DATA_COMPRESSION = ROW);
如果数据仅附加且很少更新/删除且大多数查询都是分析性的,那么甚至可以更好地使用列存储。自SQL Server 2016 SP1列存储are available across every SQL Server edition。
答案 1 :(得分:1)
作为一项实验,我尝试了两种不同的方法来比较它们。
我发现经过一些调整后,二进制版本比50版本快了约3倍。
这个场景非常具体,我的测试只测试了一些非常具体的东西。任何偏离我的测试设置都会对结果产生影响。
如何进行测试
对于50 col版本,我有50个可空的浮点列,我用float.MaxValue
填充了所有列。
对于二进制版本,我有一个列。该列的值由50x float.MaxValue + "|"
的字符串构成,所有字符串都连接成一个长字符串。然后将该字符串转换为byte []以存储在表中。
这两个表都是没有索引或约束的堆。
我的测试代码可以在https://github.com/PeterHenell/binaryBulkInsertComparison
找到我在带有SSD驱动器的6 Core工作站上运行SQL Server 2014 Developer Edition上的测试。
答案 2 :(得分:1)
我知道纯粹主义者会讨厌这种方法,但如果你的用例确实有限,那么单列样式当然会更快。
但是,说实话,如果它那么简单,那么你可以直接用简单的固定宽度格式编写/查询单个文件,然后任何数据库都能提供。备份,安全等功能都可以在文件级别完成。
有一个jdbc csv文件驱动程序,例如,如果您仍然需要类似SQL的SQL,则可以使您的文件看起来像SQL连接。我确信其他任何你编程的都存在。恐怖的提示!
另请注意,有许多数据库技术。有些针对插入性能的优化比其他针对性更好。
听起来你有类似传感器数据的东西,你的列实际上更像是一个矩阵,可能具有空间意义。在这种情况下,您可能希望查看为该数据格式明确编码的数据库技术。 SciDB就是这样一个数据库。它部分由同一个研究Vertica的人设计,因此我预计它具有相当好的摄取性能。