大规模SQL查询设计思路

时间:2010-08-13 00:40:22

标签: sql

需要查询数据库中的1200万行,处理此数据,然后将过滤后的数据插入另一个数据库。

出于显而易见的原因,我不能只从数据库中做SELECT * - 我的程序要处理的数据太多了,而且这是一个实时数据库(客户订单详情),我可以

在运行我的查询时,数据库会暂停10分钟

我正在寻找有关如何编写此程序的灵感。我来处理每一行。我当时认为最好是计算行数。然后一次抓X,等待Y秒,然后重复,直到数据集完成。这样我就不会重载数据库了,因为X足够小,所以在memmory中运行得很好。

其他建议或反馈?

4 个答案:

答案 0 :(得分:4)

我建议您阅读有关SELECT...INTO OUTFILELOAD DATA FROM INFILE的文档。

这些是将数据转储到平面文件然后将其导入另一个数据库的快速方法。

您可以转储到平面文件中,然后运行脱机脚本来处理您的行,然后在完成后将结果导入新数据库。

另见:

答案 1 :(得分:1)

随着时间的推移传播负载似乎是唯一可行的解​​决方案。究竟如何做到这在某种程度上取决于您的架构,记录如何在“实时数据库”中随时间变化,以及您的处理必须具有哪些一致性语义。

在最糟糕的情况下 - 任何记录都可以随时更改,架构中没有任何内容可以让您轻松快速地检查“最近修改,插入或删除的记录”,然而,您需要在处理过程中保持一致 - 任务根本不可行,除非您可以依赖关系引擎和/或操作系统的某些特殊支持(例如卷或文件系统“快照”,如Linux的LVM,这样可以便宜而快速地“及时冻结”数据库所在卷的副本,以便稍后使用配置为从快照卷读取的另一个只读数据库轻松获取。

但是可能你有一些约束,在模式中有助于解决这个问题,或者,人们可以希望,你可以承受由于同时发生的数据库变化而产生的一些不一致处理时间 - 一些线路处理两次,一些线路未经处理,一些线路处理旧版本,另一些处理器处于较新版本......不幸的是,您几乎没有告诉我们任何这些问题,因此提供多少线路基本上是不可行的更多的帮助。如果您编辑问题以提供有关平台,架构和数据库使用模式的更多信息,则可能会提供更多帮助。

答案 2 :(得分:0)

您没有提到您正在使用哪个数据库,但我怀疑任何可容纳1200万行的数据库实际上会尝试将所有数据一次性返回到您的程序。您的程序基本上将数据以小块(比如1000行)流式传输,通常由数据库驱动程序处理。

RDBMS具有不同的事务级别,可用于减少数据库维护一致性保证所花费的精力,这将避免锁定表。

数据库还可以创建表的快照到文件以供以后分析。

在你的位置,我会首先尝试最简单的事情,看看它是如何扩展的(在具有模拟用户访问权限的数据库的开发副本上)。

答案 3 :(得分:0)

平面文件或快照都是理想的。

如果平面文件不合适或者您无权访问快照,那么您可以使用顺序ID字段或在临时表中创建顺序ID,然后使用它进行迭代。

这样的东西
@max_id = 0

while exists (select * from table where seq_id > @max_id)
    select top n * from table where seq_id > @max_id order by seq_id
    ... process...
    set @max_id = @max seq_id from the last lot
end

如果没有顺序ID,那么您可以创建一个保存订单的临时表,如

insert into some_temp_table 
select unique_id from table order by your_ordering_scheme

然后像这样处理

... do something with top n from table join some_temp_table on unique_id ...
delete top n from some_temp_table

这样,temp_table保存了仍需要处理的记录标识符。