我需要从一个表中选择数据并将其插入另一个表中。目前SQL看起来像这样:
INSERT INTO A (x, y, z)
SELECT x, y, z
FROM B b
WHERE ...
然而,SELECT非常庞大,导致超过2百万行,我们认为它占用了太多内存。在这种情况下,Informix在运行查询时耗尽虚拟内存。
我如何选择和插入一组行(比如2000)?鉴于我认为没有任何行ID等。
答案 0 :(得分:3)
你可以从表中选择SELECT FIRST n *。其中n是您想要的行数,比如说2000.另外,在WHERE子句中,执行一个嵌入式选择,它会检查您插入的表以查找已存在的行。因此,下次运行语句时,它将不包括已插入的数据。
答案 1 :(得分:0)
我假设您有一些执行此脚本的脚本?只要您订购嵌套选择返回的值,就可以循环和限制。这是一些伪代码。
total = SELECT COUNT(x) FROM B WHERE ...
while (total > 0)
INSERT INTO A (x, y, z) SELECT x, y, z FROM B b WHERE ... ORDER BY x LIMIT 2000
total = total - 2000
end
答案 2 :(得分:0)
我几乎可以肯定IDS只允许你使用FIRST子句将数据返回给客户端 1 ,这是你想要尽可能避免的事情。
你说你得到一个内存不足错误(而不是长期事务中止错误)?您是否查看了服务器的配置以确保其具有合理的内存量?
这部分取决于您的数据集有多大,以及约束是什么 - 为什么要跨表执行加载。但我通常的目标是确定一种将数据划分为可加载子集的方法,并在循环中按顺序运行。例如,如果序列号在1到10,000,000之间,我可以运行循环十次,条件号为AND seqnum >= 0 AND seqnum < 1000000' and then
和seqnum&gt; = 1000000 AND seqnum&lt; 2000000'等。最好是能够通过变量替换范围的语言。
这有点令人讨厌,你想在范围大小方面保守一方(更小的分区而不是更小的分区 - 以减少内存不足的风险)。
1 略微过度简化。例如,存储过程必须计为“客户端”,并且存储过程中的通信成本(很多)低于转到真正客户端的成本。