NPGSQL:Потоковая передача результатов запроса Postgres?

StackOverflow https://stackoverflow.com/questions/2023913

Вопрос

У меня есть большая таблица (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:Хотя это кажется домашним заданием, это не так.Это просто более простой способ описать проблему, которая включает в себя чтение всей таблицы с помощью одного запроса, но обработку результатов по строке за раз.

Расчетное время прибытия x2:

Из npgsql Предупреждение:Существует известная проблема при вызове ExecuteReader и больших таблиц. В настоящее время Версия 1 Npgsql получает все данные из таблицы перед возвратом.Если в таких случаях вы испытываете низкую производительность, вам может потребоваться использовать серверный курсор для перелистывания строк.Для этого вы можете использовать код, подобный следующему:

Это было полезно?

Решение 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();
    }
  }
}

Другие советы

Npgsql2 теперь намного лучше обрабатывает большие наборы результатов.Он не загружает все данные в память.Таким образом, вам больше не нужно использовать курсор на стороне сервера.

Я надеюсь, что это поможет.

Франсиско Фигейредо - младший .Ведущий разработчик Npgsql

Самый простой способ сделать это -:

COPY ( select * from Table) TO STDOUT

Проверьте синтаксис copy, чтобы узнать, как распечатать его в формате .csv или любом другом формате, если вам нужно...

Чтобы распечатать всю таблицу целиком с именем столбца и значением, используйте следующий код:

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("====================");
                    }
                }
            }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top