我必须通过以下代码对Postgres执行SQL查询。查询返回大量行(40M或更多),并有4个整数字段:当我使用32Gb的工作站时,一切正常,但在16Gb工作站上,查询非常慢(由于交换,我猜)。有没有办法告诉C ++批量加载行,而不是等待整个数据集?使用Java我之前从未遇到过这些问题,因为可能有更好的JDBC驱动程序。
try {
work W(*Conn);
result r = W.exec(sql[sqlLoad]);
W.commit();
for (int rownum = 0; rownum < r.size(); ++rownum) {
const result::tuple row = r[rownum];
vid1 = row[0].as<int>();
vid2 = row[1].as<int>();
vid3 = row[2].as<int>();
.....
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
}
我正在使用PostgreSQL 9.3,在那里我看到了http://www.postgresql.org/docs/9.3/static/libpq-single-row-mode.html,但我不知道如何在我的C ++代码中使用它。我们将非常感谢您的帮助。
编辑:此查询仅运行一次,用于创建必要的主内存数据结构。因此,tt无法优化。此外,pgAdminIII可以在相同(或较小的RAM)PC下一分钟内轻松获取这些行。此外,Java可以轻松处理两倍的行数(使用Statent.setFetchSize()http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#setFetchSize%28int%29)因此,它实际上是libpqxx库的问题,而不是应用程序问题。有没有办法在C ++中强制执行此功能,而无需手动明确设置限制/偏移?
答案 0 :(得分:2)
答案 1 :(得分:1)
为了回答我自己的问题,我改编了How to use pqxx::stateless_cursor class from libpqxx?
try {
work W(*Conn);
pqxx::stateless_cursor<pqxx::cursor_base::read_only, pqxx::cursor_base::owned>
cursor(W, sql[sqlLoad], "mycursor", false);
/* Assume you know total number of records returned */
for (size_t idx = 0; idx < countRecords; idx += 100000) {
/* Fetch 100,000 records at a time */
result r = cursor.retrieve(idx, idx + 100000);
for (int rownum = 0; rownum < r.size(); ++rownum) {
const result::tuple row = r[rownum];
vid1 = row[0].as<int>();
vid2 = row[1].as<int>();
vid3 = row[2].as<int>();
.............
}
}
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
}
答案 2 :(得分:0)
光标是一个很好的起点。这是另一个光标示例,使用do-while()
const std::conStr("user=" + opt::dbUser + " password=" + opt::dbPasswd + " host=" + opt::dbHost + " dbname=" + opt::dbName);
pqxx::connection conn(connStr);
pqxx::work txn(conn);
std::string selectString = "SELECT id, name FROM table_name WHERE condition";
pqxx::stateless_cursor<pqxx::cursor_base::read_only, pqxx::cursor_base::owned>
cursor(txn, selectString, "myCursor", false);
//cursor variables
size_t idx = 0; //starting location
size_t step = 10000; //number of rows for each chunk
pqxx::result result;
do{
//get next cursor chunk and update the index
result = cursor.retrieve( idx, idx + step );
idx += step;
size_t records = result.size();
cout << idx << ": records pulled = " << records << endl;
for( pqxx::result::const_iterator row : result ){
//iterate over cursor rows
}
}
while( result.size() == step ); //if the result.size() != step, we're on our last loop
cout << "Done!" << endl;
我在应用程序中迭代了大约3300万行。除了使用游标之外,我还使用以下方法:
我知道这是您问题的很晚答案,但是我希望这可以对某人有所帮助!