NPGSQL:从 Postgres 查询流式传输结果?

发布于 2024-08-17 15:43:11 字数 694 浏览 8 评论 0原文

我有一个大表(2,000,000 行),我想将每条记录打印到屏幕上,一次一个,而不将整个表加载到内存中。

//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:虽然这看起来像是家庭作业,但事实并非如此。这只是描述问题的一种更简单的方法,该问题涉及使用单个查询读取整个表,但一次处理一行结果。

ETA x2:

来自 npgsql 警告:调用 ExecuteReader 和大型表时存在一个已知问题。 当前 Npgsql 版本 1 在返回之前从表中获取所有数据。如果您在这种情况下遇到性能不佳的情况,则可能需要使用服务器游标来分页浏览行。为此,您可以使用如下代码:

I have a large table (2,000,000 rows) and I'd like to print each record to the screen, one at time, without loading the entire table into memory.

//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

}

So as noted in the code above, the ExecuteReader() doesn't continue until the entire set is loaded into memory. How do I change this behavior so the results are streamed?

Thanks

ETA: While this seems like homework, it's not. It's just an easier way to describe a problem that involves reading an entire table with a single query but processing the results a row at a time.

ETA x2:

From npgsql
Warning: There is a known issue when calling ExecuteReader and large tables. Currently Version 1 of Npgsql gets all data from table before returning. If you are experiencing bad performance in such cases, you may need to use a server cursor to page through rows. For that, you can use a code like the following:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夜光 2024-08-24 15:43:11

Npgsql2 现在可以更好地处理大型结果集。它不会将所有数据加载到内存中。因此,您不再需要使用服务器端光标。

我希望它有帮助。

小弗朗西斯科·菲格雷多
Npgsql 首席开发人员

Npgsql2 now handles large resultsets much better. It doesn't load all data to memory. So, you don't need to use a server side cursor anymore.

I hope it helps.

Francisco Figueiredo Jr.
Npgsql Lead Developer

忆伤 2024-08-24 15:43:11

好吧,看来这是 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();
    }
  }
}

Okay, well it looks like this is a known issue with npgsql 1.0:

The workaround is to use a server cursor:

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();
    }
  }
}
幸福还没到 2024-08-24 15:43:11

最简单的方法是:

COPY ( select * from Table) TO STDOUT

检查副本的语法,了解如何以 .csv 或任何其他格式打印它(如果需要)...

The easiest way to do this is:

COPY ( select * from Table) TO STDOUT

Check the syntax of copy to see how to print it in .csv or any other format if you need to...

浅听莫相离 2024-08-24 15:43:11

要打印出包含列名称和值的整个表,请使用以下代码:

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("====================");
                    }
                }
            }

To print out the whole table with column name and value use following code:

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("====================");
                    }
                }
            }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文