2011-11-11 54 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