使用 SqlDataReader 填充 List在 c# 中
我有一个如下所示的类,
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<Student> students = new List<Student>();
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);
它工作得很好,速度也很正常。但我在自己的课程中尝试时出现什么问题?
I have a class like below,
class Student
{
public string Name {get; set;}
public string Surname {get; set;}
public int Age {get; set;}
public string Address {get; set;}
}
And I have a MySql table with 50,000 records. The Structure of the table is like below,
ID NAME SURNAME AGE ADDRESS
1 Joe Philip 20 Moscow
2 Misha Johny 25 London
...
And I have a C# code,
List<Student> students = new List<Student>();
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);
}
But it works very slow. Which method do you advice to make this code run faster?
UPDATE:
When I use this code,
DataTable dt = new DataTable();
adapter.Fill(dt);
It works very well and speed is very normal. But what is the problem I try it with my own classes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果代码运行缓慢,最大的原因是有50000条记录。对于 50,000 个
Student
对象,您到底需要什么?如果您可以找到一种方法来解决问题,而无需读取所有这些记录并创建所有这些对象,那么您将拥有更快的代码。更新
使用您自己的类就可以了。大多数情况下,运行缓慢是因为您的代码受 I/O 限制(您大部分时间都在等待 I/O)。为了避免所有这些 I/O,您可以减少检索的数据量(可能通过从数据中消除不相关的列或行)或通过更复杂的查询或存储过程对数据库进行处理。
更新 2
要回答您的后续问题(为什么创建对象列表比获取
DataSet
慢),我希望将整个查询读取为DataSet
只会比对象创建稍微快一些。我不熟悉 MySQL .NET 库是如何实现的。令我惊讶的是,这两种方法在速度上会有巨大差异。也许MySqlDataReader
正在做一些愚蠢的事情,比如使用内部DataSet
。如果两者之间的性能有很大差异,那么该库的作者可能应该修复它。更新3
此答案针对MySqlDataAdapter 或 MySqlDataReader批量传输? 有一个很好的提示;设置阅读器的
BatchSize
可能会有所帮助。如果批量大小对于读者来说太小,那么处理像您这样的大量记录时,效率就会降低。If the code runs slowly, the largest cause is that there are 50,000 records. What exactly do you need with 50,000
Student
objects? If you can find a way to solve your problem without reading all of those records and creating all of those objects, you'll have faster code.Update
Using your own class is fine. Most of the time when things run slow, it's because your code is I/O bound (you spend most of your time waiting for I/O). To avoid all that I/O, you can reduce the amount of data you retrieve (perhaps by eliminating irrelevant columns or rows from your data) or doing your processing on the database through a more complex query or stored procedure.
Update 2
To answer your follow-up question (why creating a list of objects is slower than getting a
DataSet
), I would expect that reading the entire query as aDataSet
would only be slightly faster than object creation. I'm not familiar with how that MySQL .NET library is implemented. It is surprising to me that the two methods would have a large difference in speed. MaybeMySqlDataReader
is doing something dumb like using an internalDataSet
. If the performance is drastically different between the two, it's probably something the author of that library should fix.Update 3
This answer for MySqlDataAdapter or MySqlDataReader for bulk transfer? has a good tip; setting the
BatchSize
of the reader may be helpful. If the batch size is too small for the reader, that would make it less efficient with a large number of records like yours.使用记录索引代替 coulmname 可以使性能更好一些
使用
Using index of record instead of coulmname make the performance a bit better
use