我正在尝试将数据从数据库中的表导出为csv
格式的文件。
我想出了以下程序。
我的表包含大约13 million
行,这个程序非常慢。
如何加快此计划?
#include <iostream>
#include <occi.h>
#include <stdlib.h>
#include <fstream>
using namespace std;
int main()
{
oracle::occi::Environment* environment;
oracle::occi::Connection *con;
oracle::occi::Statement* stmt;
oracle::occi::ResultSet* res;
try
{
ofstream outfile;
outfile.open("example.txt");
string user ; cin>>user;
string pass ; cin>>pass;
string instance ; cin >>instance;
environment = oracle::occi::Environment::createEnvironment(oracle::occi::Environment::DEFAULT);
con = environment->createConnection(user,pass,instance);
string query = "SELECT A,B FROM TABLE_X";
stmt = con->createStatement(query);
res = stmt->executeQuery();
while (res->next())
{
outfile<<res->getInt(1)<<','<<res->getInt(2)<<'\n';
}
outfile.close();
stmt->closeResultSet(res);
con->terminateStatement(stmt);
environment->terminateConnection(con);
}catch(oracle::occi::SQLException &e){
std::cout<<e.what();
}
return 0;
}
答案 0 :(得分:3)
使用数组提取来减少数据库往返。以下内容来自here。我将尝试使用值20,50,100,1000来查找下面示例中“NumROws”的最佳值。
示例11-1如何对ResultSet使用数组提取
ResultSet *resultSet = stmt->executeQuery(...);
resultSet->setDataBuffer(...);
while (resultSet->next(numRows) == DATA_AVAILABLE)
process(resultSet->getNumArrayRows() );
这导致每个数据的数量最多为numRows 柱。使用setDataBuffer()接口指定的缓冲区 应足够大,至少可以容纳数量的数据。
另一种策略是按范围分割任务并使它们并行运行。如果导出数据必须在单个文件中,那么您可以单独合并它们(cat file1 file2&gt; file)。
您要写入的文件系统怎么样?它慢吗?你有没有尝试过写一个不同的地方?在正在写入输出的文件系统中。
答案 1 :(得分:0)
我不知道你叫什么慢。但是,与数据库提取无关,您可以使用write()
而不是operator<<
显着提高文件i / o的写入性能。
像我这样编写100万个随机csv对的小基准测试表明,在我糟糕的win8 pc上有以下表现:
operator<< outputs at a rate of 7 Mb/s
write() outputs at a rate of 40 Mb/s
速度提高5倍以上,即1300万条目约30秒。
然而,看起来很宽松的代码,让你高兴看看它是否值得付出努力:
os << x << ',' << y << '\n';
成为
p=itoa(x, buff, 10);
while(*p)
p++;
*p++ = ',';
itoa(y, p, 10);
while(*p)
p++;
*p++ = '\n';
*p++ = '\0';
os.write(buff, p - buff);
其中buff是在循环外部分配的缓冲区。