我是 Informix 的新手,作为测试活动的一部分,我需要为 Oracle、Informix 和 Sybase 创建 2TB+ 大小的数据。有没有一种数据库中立的方式来做到这一点?
我也在寻找任何免费软件或开源工具;我可以为 Oracle 找到一些,但对于 Informix 和 Sybase 几乎没有。
以这种方式跨多个数据库工作是一项艰巨的任务。坦率地说,2TB 正好是这些产品所能达到的最高端(除非您使用的是 Sybase IQ - 您没有提到)。如果您正在根据这些数据进行数据仓库或报告,那么您可能需要重新考虑您的产品选择。
{如果您解释了为什么要加载 2TB 的测试数据,给您建议会更容易。另外,为什么要使用这些数据库?在 Oracle 中加载的“技巧”对于 Sybase 会有所不同。无论如何,这是我的一般建议……}
首先,检查您的 DDL 并完全删除所有约束和自动递增值。当您进行任何类型的插入时,数据库会花费大量 CPU 和 IO 周期检查这些值,因此请摆脱它们。如有必要,以后重新应用它们会更快。
其次,为您希望在最终表中包含的每一列生成一个 1 列表。例如,如果这是一个地址表,您可能有:
First_Name, Last_Name, Address_1, etc.
用您在实际数据中期望的值的小样本填充每个表,例如每个表 10 行。
现在来看看魔术:您将所有这些 1 列表交叉连接到一个笛卡尔积中。这将为您的 1 个列表的每个可能组合提供 1 行,从而将它们“膨胀”到您需要的大小。
示例查询:(语法可能因数据库而异)
SELECT *
FROM First_Name
CROSS JOIN Last_Name
CROSS JOIN Address_1
…
CROSS JOIN Post_Code
您可以通过乘以行数来计算将生成多少数据。
10 tables w/ 10 rows
= 10^10
= 10,000,000,000
= 10 billion rows
然后将您的行数乘以平均行大小以获得总数据量,不包括数据库开销。
(128 byte rows * 10 billion rows) / 1024^4 (Terabyte)
= 1.164 Terabytes of sample data.
从 Quest 下载 Benchmark Factory 的试用版。这将允许您将几个不同的基准数据集推送到您的数据库中并运行它们。不过如果你想继续使用它并不便宜。
以指数方式增长数据
插入到 my_table SELECT * FROM my_table;
如果您需要唯一的主键字段,请将它们替换为 Oracle 相关插入中的序列以及其他数据库的等效项。
如果您的硬件无法处理翻倍 100G+ 数据的负载,请分小批进行。对 Oracle 使用 WHERE rownum < 100000...,对其他数据库使用任何等效项。
您将面临许多问题。最大的可能是不同的 DBMS 都有不同的首选加载格式 - 因此任何单一数据格式都需要对一个或多个 DBMS 进行一些操作 - 除非您直接生成 INSERT 语句。
Informix 更喜欢一种可以松散地描述为“使用反斜杠作为转义符和(未转义的)换行符指示记录结束的定界字段”的格式。默认分隔符是管道符号“ |
”,但可以更改以适合。例如:
100|Some string|2008-09-12|23.145|wc -l \| sort -n|76:34:45.219
幸运的是,日期格式相当灵活。如果您想了解可怕的细节,请从IIUG源代码存档下载 SQLCMD 的源代码(不是 Microsoft 篡夺者 - 原始的)并阅读文件unload.format
。在 Informix 中加载 CSV 数据并不是一件容易的事——尽管我确实调用了一个 Perl 脚本csv2unl
来很大程度上自动化从 CSV 到 Informix UNLOAD 格式的转换(也应该在 IIUG 网站上提供)。
正如@St3fan 建议的那样,任何主要的脚本语言都可以用来生成数据。我会使用 Perl,但这主要是因为我很久以前就学过 Perl,因此对它最满意。
要考虑的另一个问题是您是为单个表(或一组不相关的表)还是为一组相关表生成数据。例如,为单个表生成数据相对容易;为共享公共字段的两个表(例如,Orders 表和 OrderItems 表)生成数据要困难得多。
即便如此,2 TB 也是一项相当艰巨的任务。即使每行是 1 KB,您也需要生成大约 20 亿行数据。您将需要分块加载数据 - 而不是全部在单个事务中。您可能希望在加载后创建索引 - 但这让您有责任确保表中的数据有效(没有不适当的重复)。如果您使用的是 SERIAL 列(Informix 表示自动生成的值),您可能需要使用 BIGSERIAL(或者可能是 SERIAL8 - 这取决于您使用的 Informix 版本,但它应该是 IDS 11.50,在这种情况下BIGSERIAL 是更好的选择)。
@dotIN 询问时间......加载多长时间?
让我们回顾一些基本原理......写入磁盘的体面写入速率是多少?100 MB/s 持续?让我们以它为起点。
以 100 MB/s 的速度写入数据,需要:
2,000,000 MB / 100 MB/s = 20,000 s
大约是6个小时。
我认为这是一个非常高的比率;此外,您必须将数据发送到 DBMS(因此您必须让语句以对应于 100 MB/s 的速率执行),此外您还必须担心活动的数据库日志记录,等等。如果负载可以有效地分布在多个磁盘上,您可能会接近它。但是,很容易受 I/O 限制,特别是如果您的机器没有多个可单独寻址的磁盘驱动器(例如,单个多 TB RAID 驱动器,具有单个 I/O 通道)。
如果每一行都是通过单独的 INSERT 语句加载的,那么您必须每秒执行大量语句。这是另一个性能抑制剂。您没有确切说明您是如何进行加载的,但是在处理大量数据时,您必须非常小心,并且需要技巧和经验才能从任何一个 DBMS 中获得最佳性能 - 更不用说所有这些了. 请注意,当您不再寻求加载而是提取信息时,加速 TB 数据加载性能的配置不一定会带来良好的性能。
并且提到了斑点;这些有特殊的限制,需要在每个系统上仔细处理,并且通常会使故事复杂化。(例如,在 IDS 中,您需要一个单独的 Smart BlobSpace 用于智能 blob - BLOB 或 CLOB 类型 - 从存储数据的 DBSpace。如果您使用的是老式 BYTE 或 TEXT blob,您可能希望使用适当的 BlobSpace - 与 Smart BlobSpace 不同 - 其页面大小配置为适合您存储的数据。您可能不想将 BYTE 或 TEXT blob 存储在 TABLE 中 - 它可以工作,但它会影响日志系统,这就是为什么首先可以选择 BlobSpaces 的原因。)
我已经多次使用一些简单的 Python、Perl 或 Ruby 脚本来生成 SQL 语句或某些特定于数据库的工具可以导入的 CSV 样式文件。
不过,2 TB 已经很多了。您可能希望分批进行。
我有一个 2TB+ (nrows=10M, rowsize=2048) ascii 测试文件(带有管道分隔符),它具有唯一性:全名、地址、电话号码和各种其他数据类型,如 DATE、SMALLINT、DECIMAL (9,2)、等用于测试/基准测试目的。
问题是。我怎样才能把它给你?
对于任何允许访问数据库的编程语言来说,这都不是问题。