2009-07-27 412 views
3

我目前填充業務對象的方式是使用類似於下面的snipet的東西。提高DAL性能

using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.CDRDatabase)) 
{ 
    using (SqlCommand comm = new SqlCommand(SELECT, conn)) 
    { 
     conn.Open(); 

     using (SqlDataReader r = comm.ExecuteReader(CommandBehavior.CloseConnection)) 
     { 
      while (r.Read()) 
      { 
       Ailias ailias = PopulateFromReader(r); 
       tmpList.Add(ailias); 
      } 
     } 
    } 
} 

private static Ailias PopulateFromReader(IDataReader reader) 
{ 
    Ailias ailias = new Ailias(); 

    if (!reader.IsDBNull(reader.GetOrdinal("AiliasId"))) 
    { 
     ailias.AiliasId = reader.GetInt32(reader.GetOrdinal("AiliasId")); 
    } 

    if (!reader.IsDBNull(reader.GetOrdinal("TenantId"))) 
    { 
     ailias.TenantId = reader.GetInt32(reader.GetOrdinal("TenantId")); 
    } 

    if (!reader.IsDBNull(reader.GetOrdinal("Name"))) 
    { 
     ailias.Name = reader.GetString(reader.GetOrdinal("Name")); 
    } 

    if (!reader.IsDBNull(reader.GetOrdinal("Extention"))) 
    { 
     ailias.Extention = reader.GetString(reader.GetOrdinal("Extention")); 
    } 

    return ailias; 
} 

有沒有人有任何建議如何提高這樣的表現?請記住,對於某些類型,PopulateFromReader包含更多的數據庫查詢以便完全填充對象。

+0

你確實有性能問題嗎?使用DataReader幾乎是最好和最快的方法 - 所有其他方法通常基於DataReader。 – 2009-07-27 11:01:17

+0

在不同的表中發生問題的地方,在PopulateFromReader方法中發生multipul查找。我正在嘗試診斷問題的出處,無論是DAL,服務器(不太可能)的表結構還是帶寬。 – 2009-07-27 11:10:56

回答

7

一個明顯的變化就是要取代這種說法: ailias.AiliasId = reader.GetInt32(reader.GetOrdinal(「AiliasId」));

ailias.AiliasId = reader.GetInt32(constAiliasId); 

其中constAiliasId是一個常數保持場AiliasId的序號。

這可以避免在循環的每次迭代中進行有序查找。

0

AFAIK,這是最快的。 SQL查詢/服務器的速度可能很慢。或者別的地方。

5

如果數據量很高,那麼可能會發生構建巨大列表的開銷可能成爲瓶頸;在這種情況下,使用流式對象模型會更有效率;即

public IEnumerable<YourType> SomeMethod(...args...) { 
    using(connection+reader) { 
     while(reader.Read()) { 
      YourType item = BuildObj(reader); 
      yield return item; 
     } 
    } 
} 

消費代碼(通過foreach等),然後僅具有單個對象來處理(一次)。如果他們想要獲得一個列表,他們可以(與新的List<SomeType>(sequence),或在.NET 3.5:sequence.ToList())。

這涉及幾個方法調用(每個序列項附加MoveNext()/Current,隱藏在背後的foreach),但是當你有外的工藝數據,如從數據庫中你永遠不會注意到這一點。

1

您的代碼看起來幾乎與我們的許多業務對象加載函數相同。當我們懷疑DAL性能問題時,我們會看一些事情。

  1. 我們跳出數據庫多少次?有什麼方法可以減少連接次數,並通過使用多個結果集(我們使用存儲過程)帶回較大的數據塊。因此,不是每個子對象加載自己的數據,父代都會爲自己提取所有數據和它的孩子。您可以運行脆弱的SQL(需要匹配的排序順序等)和棘手的循環來遍歷數據讀取器,但我們發現它比多個數據庫行程更優化。

  2. 啓動數據包嗅探器/網絡監視器以查看導線上正在傳輸多少數據。看到一些結果集有多大,你可能會感到驚訝。如果是,那麼你可能會考慮採用其他方式來解決問題。像懶/推遲加載一些子數據。

  3. 確保您使用的是您要求的所有結果。例如,從SELECT * FROM(返回30個字段)到簡單的SELECT Id,Name FROM(如果這是你需要的)可能會產生很大的差異。

0

很可能真正的問題是您提到的多個每個對象的查找。你仔細觀察過,看看它們是否都可以放入一個存儲過程?