1

インデックスのないSQLServerテーブルがあり、追加できません。そのテーブルには何百万ものレコードがあり、メモリが不足しているため、1回のクエリですべてのレコードを取得することはできません。

すべてのレコードを小さな部分で取得するにはどうすればよいですか(たとえば、部分ごとに100レコード)。

4

4 に答える 4

1

どのように記録を読み取ろうとしていますか? を使用する場合SqlDataReader、メモリ不足の問題は発生しません。


const string QUERY = "SELECT * FROM MyTable";
using (var conn = new SqlConnection(CONNECTION_STRING))
{
    using (var cmd = new SqlCommand(QUERY, conn))
    {
        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                // Use properties and methods of the reader to access the current row
            }
        }
    }
}

これにより、データベース接続全体で一度に 1 行が渡されます。接続はバッファリングを行い、データベースから複数の行を取得して、一度に 1 つずつ渡します。

于 2009-12-29T13:22:51.720 に答える
1

これは、カーソルを実際の目的で使用できるまれなケースの 1 つです。

静的カーソルを作成し (これにより、テーブル データのコピーが作成されますが、クライアント側ではなくサーバーの一時データベースに作成され、並べ替えられます)、このカーソルを参照できます。

于 2009-12-29T13:26:32.447 に答える
0

解決策の 1 つは、Quassnoi が既に提案したように、サーバー側のカーソルを使用することです。その欠点は、テーブル全体のコピーが tempdb に作成されることを意味する静的カーソルでなければならないことです。

別の解決策は、クライアント側をストリーム指向の方法で行ごとに処理することです (つまり、クライアント側のカーソル)。

 using(SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
 {
   while (rdr.Read())
   {
     -- process one row here
   }
 }

このようにして、クライアント側のメモリをすべて使い果たすことなく、大きな行セットを処理できます。

于 2009-12-29T16:08:56.473 に答える
0

1 つの解決策は、ダンプする必要があるすべてのテーブルを ID 列のある一時テーブルに選択することです。私は別々のアプリケーションサーバーとデータベースサーバーを持っており、DBサーバーにはこれに十分なメモリがあるため、これは...許容できるソリューションです。しかし、おそらくもっと効果的な解決策がありますか?

于 2009-12-29T13:20:08.843 に答える