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 ResultSetでArray Fetchを使用する方法

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

これにより、列ごとに最大 numRows の量のデータがフェッチされます。setDataBuffer() インターフェイスで指定されたバッファは、少なくとも numRows のデータを保持するのに十分な大きさである必要があります。

もう 1 つの戦略は、タスクを範囲ごとに分割し、これらを並行して実行することです。エクスポート データを 1 つのファイルにする必要がある場合は、それらを個別にマージできます ( cat file1 file2 > file )。

あなたが書き込んでいるファイルシステムはどうですか?遅いですか?別の場所に書き込んでみましたか? 出力が書き込まれるファイルシステムで。

于 2015-05-30T18:46:43.617 に答える
0

私はあなたが遅いと呼ぶものを知りません。ただし、データベースの取得とは別に、write()代わりにoperator<<.

あなたのような100万個のランダムなcsvペアを書く小さなベンチマークは、私の貧弱なwin8 pcで次のパフォーマンスを示しました:

operator<<  outputs at a rate of 7 Mb/s
write()     outputs at a rate of 40 Mb/s

これは 5 倍以上高速です。つまり、1,300 万件のエントリで約 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 に答える