C#でList <T>を埋め込むためにSqlDataReaderを使用する

私は以下のようなクラスを持っていますが、

class Student
{
    public string Name {get; set;}
    public string Surname {get; set;}
    public int Age {get; set;}
    public string Address {get; set;}
}

私は50,000レコードのMySqlテーブルを持っています。表の構造は以下の通りですが、

ID        NAME       SURNAME        AGE          ADDRESS
1         Joe        Philip         20           Moscow
2         Misha      Johny          25           London
...

私はC#コードを持っていますが、

List students = new List();
string sql = "SELECT name,surname,age,address FROM Students";
command.CommandText = sql;
MySqlDataReader reader = command.ExecuteReader();
while(reader.Read())
{
    Student st = new Student();
    st.Name = reader["Name"].ToString();
    st.Surname = reader["Surname"].ToString();
    st.Age = Convert.ToInt32(reader["Age"].ToString());
    st.Address = reader["Address"].ToString();
    students.Add(st);
}

しかし、それは非常に遅く動作します。このコードをより速く実行するにはどの方法をアドバイスしますか?

更新:

このコードを使用すると、

DataTable dt = new DataTable();
adapter.Fill(dt);

それは非常にうまく動作し、速度は非常に正常です。しかし、自分の授業でそれを試してみるとどういう問題がありますか?

1
このために私がこのデータセットを使用すると、このデータはすべて墓地に置かれます。だから私は自分のクラスを使いたいのですが違いは何ですか?
追加された 著者 namco,
私の答えを見てください。この生徒データを使って何をしようとしているのかを教えてくれれば、おそらくもっと良い答えが得られます。
追加された 著者 Jacob,
より大きなポイントは、必ずデータベースからすべてのレコードをロードする必要はないということです。データのサブセットのみが必要な場合は、 where 節でクエリを制限できます。
追加された 著者 Jacob,
好奇心のために、データベーステーブル全体をまったくのメモリに読み込む必要があるのはなぜですか?データベースには、メモリに収まるよりもはるかに多くのデータを保管することができ、レコードごとにデータレコードを処理する必要があるという一般的な考え方です。
追加された 著者 Vlad,
これはおそらく実現するほど速く、ここには明らかな拡張や見落としはありません。これらのレコードはすべてメモリ上に必要ですか?
追加された 著者 BrokenGlass,
そのコードはコンパイルされません。 stringint プロパティ(age)に代入しています。
追加された 著者 Klaus Byskov Pedersen,
もちろんそれは遅いです。一度に50kレコードをメモリに読み込まないでください!
追加された 著者 Gabe Moothart,

2 答え

コードが遅く実行される場合、最大の原因は50,000レコードがあることです。 50,000の Student オブジェクトで正確に必要これらのレコードをすべて読み込まずにこれらのオブジェクトをすべて作成せずに問題を解決する方法を見つけることができれば、より高速なコードを作成できます。

更新

自分のクラスを使っても問題ありません。ほとんどの場合、コードが I/Oバウンド(I/Oを待っている時間のほとんどを費やしている)なので、物事が遅くなるほとんどの場合です。そのI/Oをすべて回避するには、(データから無関係な列や行を削除するなどして)取得するデータの量を減らすか、より複雑なクエリやストアドプロシージャを使用してデータベースを処理します。

更新2

DataSet を取得するよりオブジェクトのリストを作成する方が遅いのですが)、質問全体を DataSet として読むことは、オブジェクトの作成よりもわずかに高速です。私は、MySQL .NETライブラリがどのように実装されているかに精通していません。 2つの方法が大きな速度の差を持つことは私には驚くべきことです。たぶん MySqlDataReader は、内部の DataSet のような何かをやっているかもしれません。両方のパフォーマンスが大きく異なる場合は、おそらくそのライブラリの作成者が修正する必要があります。

更新3

この回答は、バルク転送のMySqlDataAdapterまたはMySqlDataReader には良い先端;読者の BatchSize を設定すると便利です。バッチサイズが読者にとって小さすぎると、あなたのような多数のレコードで効率が低下します。

5
追加された
私は試験検査プログラムを書く。私はこれと私がここで学生のポイントを決定するために示していない別のデータを使用します。ここではStudentクラスの代わりにDataSetを使用できます。しかし私は自分のクラスを使うことを好む。 RAMに問題はありません。 List with Dataの塗りつぶしにのみ問題があります。非常に遅いです。
追加された 著者 namco,
あなたがデータ上で行っている処理の種類を知らなければ、それ以上の助けはできません。より高速なコードは少ないコードなので、コードを少なくする方法を見つけることができます(たとえば、データベースへの処理をオフロードするなど)。私の更新を参照してください。
追加された 著者 Jacob,

coulmnameの代わりにインデックスを使用すると、パフォーマンスが少し向上します つかいます

st.Name = reader[0].ToString();
instead of
st.Name = reader["Name"].ToString();

and 
st.Name = reader[0].ToString();
instead of 
st.Name = reader["surname"].ToString();
1
追加された
また、文字列のインデックスは適切な大文字と小文字の区別が必要であることに注意してください。それ以外の場合は非常に遅くなります。この場合、MySQL ADO.NETの実装は奇妙です。 MySQL ADOのためだけに、私がテストした他のすべてのコネクタが正常に動作しました。
追加された 著者 nawfal,