1

我正在尝试将数据从数据库中的表导出到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;
}
4

2 回答 2

3

使用数组获取来减少数据库往返。以下内容来自这里。在下面的示例中,我将尝试使用值 20,50,100,1000 来找到“NumROws”的最佳值。

示例 11-1 如何将 Array Fetch 与 ResultSet 一起使用

ResultSet *resultSet = stmt->executeQuery(...);
resultSet->setDataBuffer(...);
while (resultSet->next(numRows) == DATA_AVAILABLE)
   process(resultSet->getNumArrayRows() );

这会导致为每列获取最多 numRows 数量的数据。使用 setDataBuffer() 接口指定的缓冲区应该足够大以至少容纳 numRows 数据。

另一种策略是按范围拆分任务并让它们并行运行。如果导出数据必须在单个文件中,那么您可以单独合并它们(cat file1 file2 > file)。

你正在写入的文件系统呢?慢吗?您是否尝试过写信到不同的位置?在输出被写入的文件系统中。

于 2015-05-30T18:46:43.617 回答
0

我不知道你说的慢。但是独立于数据库获取,您可以通过使用write()而不是operator<<.

像你这样写 100 万个随机 csv 对的小基准测试在我可怜的 win8 电脑上显示了以下性能:

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 是在循环外分配的缓冲区。

于 2015-05-30T19:05:10.863 回答