2

大きなテーブル (2,000,000 行) があり、テーブル全体をメモリにロードせずに、各レコードを一度に 1 つずつ画面に出力したいと考えています。

//pseudo code
var cmd = new NpgSQLCommand();
cmd.CommandText = "SELECT * FROM mytable;"
IReader reader = cmd.ExecuteReader(); //blocks until the entire set is returned

while(reader.Read()) //ideally each call to read loads more results from the db.
{
// print record name

}

したがって、上記のコードに示されているように、セット全体がメモリにロードされるまで ExecuteReader() は続行されません。結果がストリーミングされるように、この動作を変更するにはどうすればよいですか?

ありがとう

ETA: これは宿題のように思えますが、そうではありません。これは、1 つのクエリでテーブル全体を読み取り、一度に 1 行ずつ結果を処理するという問題を説明する簡単な方法です。

ETA x2:

npgsql からの警告: ExecuteReader と大きなテーブルを呼び出す場合、既知の問題があります。現在、Npgsql のバージョン 1 は、返す前にテーブルからすべてのデータを取得します。このような場合にパフォーマンスが低下する場合は、サーバー カーソルを使用して行をページングする必要がある場合があります。そのためには、次のようなコードを使用できます。

4

4 に答える 4

4

Npgsql2 は、大きな結果セットをより適切に処理できるようになりました。すべてのデータをメモリにロードするわけではありません。したがって、サーバー側のカーソルを使用する必要はもうありません。

お役に立てば幸いです。

Francisco Figueiredo Jr. Npgsql 主任開発者

于 2010-01-08T02:48:22.167 に答える
2

さて、これは npgsql 1.0 の既知の問題のようです。

回避策は、サーバー カーソルを使用することです。

using System;
using System.Data;
using Npgsql;

public static class NpgsqlUserManual
{
  public static void Main(String[] args)
  {
    NpgsqlConnection conn = new NpgsqlConnection("Server=127.0.0.1;Port=5432;User Id=joe;Password=secret;Database=joedata;");
    conn.Open();

    NpgsqlCommand command = new NpgsqlCommand("select version()", conn);
    String serverversion;

    try
    {
      serverversion = (String)command.ExecuteScalar();
      Console.WriteLine("PostgreSQL server version: {0}", serverversion);
    }


    finally
    {
      conn.Close();
    }
  }
}
于 2010-01-07T22:05:19.680 に答える
0

これを行う最も簡単な方法は次のとおりです。

COPY ( select * from Table) TO STDOUT

コピーの構文をチェックして、必要に応じて.csvまたはその他の形式で印刷する方法を確認してください...

于 2013-02-16T12:23:18.740 に答える
0

列名と値を含むテーブル全体を出力するには、次のコードを使用します。

using (var conn = new NpgsqlConnection("Host=IPADDRESS;Username=USER;Password=PASS;Database=DBNAME;"))
        {
            conn.Open();
            using (var cmd = new NpgsqlCommand())
            {
                cmd.Connection = conn;

                cmd.CommandText = "SELECT * FROM TABLE_NAME";

                StringBuilder str;
                int count;

                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        str = new StringBuilder();
                        count = 0;

                        while (count < reader.FieldCount) {
                            str.Append(reader.GetName(count) + ": " + reader.GetValue(count));

                            if ((count + 1) < reader.FieldCount)
                            {
                                str.Append(", ");
                            }

                            count++;
                        }

                        Console.WriteLine(str.ToString());
                        Console.WriteLine("====================");
                    }
                }
            }
于 2016-02-10T03:41:03.077 に答える