2011-11-11 78 views
1

填充列表 我有一类像下面, 使用SqlDataReader对象在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); 
} 

但它的工作原理很慢。您建议如何使代码运行得更快?

UPDATE:

当我使用此代码,

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

它工作得很好,速度是非常正常的。但是,我用我自己的课程尝试这个问题有什么问题?

+7

当然是缓慢的。不要一次将50k条记录读入内存! –

+3

这可能会达到最快,这里没有明显的增强或忽略 - 你是否需要记忆中的所有记录? – BrokenGlass

+0

出于好奇,为什么你需要将整个数据库表读入内存_at all_?数据库的总体思想是,它们可能保存的数据比可以放入内存的数据多得多,并且我们应该通过记录来处理数据记录。 – Vlad

回答

5

如果代码运行缓慢,最大的原因是有50,000条记录。你究竟做了什么需要有50,000个Student对象?如果你可以找到解决问题的方法,而无需阅读所有这些记录并创建所有这些对象,那么代码就会更快。

更新

使用自己的类是好的。大多数情况下,当事情运行缓慢时,这是因为您的代码是I/O限制(您花费大部分时间等待I/O)。为了避免所有I/O,您可以通过更复杂的查询或存储过程来减少检索的数据量(可能通过消除数据中不相关的列或行)或对数据库执行处理。

更新2

要回答你的后续问题(为什么创建对象的列表比获得一个DataSet慢),我希望看完整个查询作为DataSet只会略快比创建对象。我不熟悉如何实现MySQL .NET库。我很惊讶这两种方法的速度差异很大。也许MySqlDataReader正在做一些愚蠢的事情,如使用内部DataSet。如果两者的表现完全不同,那么这个图书馆的作者应该修正这个问题。

更新3

这个答案MySqlDataAdapter or MySqlDataReader for bulk transfer?有一个很好的提示;设置读者的BatchSize可能会有所帮助。如果批量大小对于读者来说太小,那么对于大量像您的记录那样的记录而言效率会降低。

+0

我写考试检查程序。我会用这个和其他数据,我没有在这里展示用于确定学生的点。我可以在这里使用DataSet而不是Student类。但我更喜欢用我自己的班级。 RAM没有任何问题。仅在填充数据列表时出现问题。它工作非常缓慢。 – namco

+0

不知道什么样的处理你的数据做的,我们不能给更多的帮助的具体细节。更快的代码是代码,不会少,所以要尽量找到一种方法,让你的代码少做(卸载一些处理以数据库为例)。查看我的更新。 – Jacob

+1

请参阅相关的问题http://stackoverflow.com/questions/2768828/mysqldataadapter-or-mysqldatareader-for-bulk-transfer/2823515#2823515 – Jacob

1

使用记录,而不是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