问题描述
我有一张10000万行的表。数据库中的表大小约为25 GB。
我需要将此数据卸载到csv文件中。
什么是最好的最快的方法来做到这一点。
我正在阅读有关使用cta来执行此操作的外部表,但我认为没有选择直接创建为CSV格式的表的选项,该格式创建ascii文件逗号分隔。它只给出了作为dmp oracle loader二进制文件的选项。
有没有办法做外部表-cta与服务器上的输出为CSV-acsii文件?我认为那将是理想的。
sql loader是将数百万个数据加载到oracle数据库中的本地行业之王,但为什么不反过来呢?
我尝试使用sql developer导出到csv,由于10000万行,它需要很长时间才能完成。100万行csv导出大约需要2个小时,因此您可以想象使用sql developer将是一个200小时的工作。
蟾蜍只是在这次尝试中崩溃了。
我尝试了sqlplus假脱机,这也花了很长时间,因为它必须扫描整个10000万数据集。
我没有尝试过去使用的旧utl文件。我不知道在这个新的多云世界中甚至支持此文件或utl文件的12c增强功能。但是任何顺序的事情都需要很长时间。
Spark和Cassandra可以并行化并在几分钟内完成此操作,但这是一个不同的架构。我的数据驻留在Oracle中
有没有一种方法可以并行化并在百万块中执行此操作,那么我可以合并unix中的100文件。
请建议?
我需要将此数据卸载到csv文件中。
什么是最好的最快的方法来做到这一点。
我正在阅读有关使用cta来执行此操作的外部表,但我认为没有选择直接创建为CSV格式的表的选项,该格式创建ascii文件逗号分隔。它只给出了作为dmp oracle loader二进制文件的选项。
有没有办法做外部表-cta与服务器上的输出为CSV-acsii文件?我认为那将是理想的。
sql loader是将数百万个数据加载到oracle数据库中的本地行业之王,但为什么不反过来呢?
我尝试使用sql developer导出到csv,由于10000万行,它需要很长时间才能完成。100万行csv导出大约需要2个小时,因此您可以想象使用sql developer将是一个200小时的工作。
蟾蜍只是在这次尝试中崩溃了。
我尝试了sqlplus假脱机,这也花了很长时间,因为它必须扫描整个10000万数据集。
我没有尝试过去使用的旧utl文件。我不知道在这个新的多云世界中甚至支持此文件或utl文件的12c增强功能。但是任何顺序的事情都需要很长时间。
Spark和Cassandra可以并行化并在几分钟内完成此操作,但这是一个不同的架构。我的数据驻留在Oracle中
有没有一种方法可以并行化并在百万块中执行此操作,那么我可以合并unix中的100文件。
请建议?
专家解答
你说得对,你不能使用外部表将cta导出到CSV。
这里有几件事你可以尝试。我假设你有一张这样的表:
SQLcl parallel spool
您可以利用SQLcl中的CSV sql格式以该格式抽出数据。并使用并行提示让许多进程运行您的查询。那么你只需要假脱机输出:
DIY parallelism with UTL_FILE
您可以使用utl_file构建一个PL/SQL例程,以从表中导出一系列数据:
当您导出数百万行时,您可能需要更改批量收集以使用具有限制的显式游标。否则您可能会用完PGA! ;)
然后使用dbms_parallel_execute调用这个这将提交N个作业产生N个文件,你可以合并在一起:
HT to Sean Stuber for PL/SQL dbms_parallel_execute示例:https://seanstuber.wordpress.com/2013/10/17/parallel-plsql-with-dbms_parallel_execute/
这里有几件事你可以尝试。我假设你有一张这样的表:
create table t as select rownum x, sysdate y from dual connect by level <= 1000;
SQLcl parallel spool
您可以利用SQLcl中的CSV sql格式以该格式抽出数据。并使用并行提示让许多进程运行您的查询。那么你只需要假脱机输出:
set term off set feed off set sqlformat csv spool out.csv select /*+ parallel */* from t; spool off
DIY parallelism with UTL_FILE
您可以使用utl_file构建一个PL/SQL例程,以从表中导出一系列数据:
create or replace procedure csv_unload (
start_id t.x%type, end_id t.x%type
) as
type t_tab is table of t%rowtype;
rws t_tab;
output utl_file.file_type;
filename varchar2(100);
begin
select *
bulk collect into rws
from t
where x between start_id and end_id;
filename := 't_' || start_id || '_' || end_id || '.csv';
execute immediate 'alter session set nls_date_format=''YYYY/MM/DD''';
output := utl_file.fopen ( 'TMP', filename, 'w' );
utl_file.put ( output, 'X,Y' );
for i in 1 .. rws.count loop
utl_file.put_line ( output, rws(i).x || ',' || rws(i).y );
end loop;
utl_file.fclose ( output );
end csv_unload;
/当您导出数百万行时,您可能需要更改批量收集以使用具有限制的显式游标。否则您可能会用完PGA! ;)
然后使用dbms_parallel_execute调用这个这将提交N个作业产生N个文件,你可以合并在一起:
declare
task varchar2(30) := 'parallel_unload';
plsql varchar2(1000);
begin
dbms_parallel_execute.create_task( task_name => task );
dbms_parallel_execute.create_chunks_by_sql(
task_name => task,
sql_stmt => 'with grps as (
select ntile(10) over (order by x) grp, t.*
from t
)
select min(x) start_id, max(x) end_id from grps
group by grp',
by_rowid => false
);
plsql := q'[begin
csv_unload( :start_id,:end_id );
end;]';
dbms_parallel_execute.run_task(
task_name => task,
sql_stmt => plsql,
language_flag => dbms_sql.native,
parallel_level => 10
);
dbms_parallel_execute.drop_task( task_name => task );
end;
/HT to Sean Stuber for PL/SQL dbms_parallel_execute示例:https://seanstuber.wordpress.com/2013/10/17/parallel-plsql-with-dbms_parallel_execute/
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




