2009-08-28 74 views
13

我決定不使用orm並將直接使用ADO.NET用於我的項目。我知道我知道編程需要更長的時間,但我只是希望頁面在高峯時間以高速加載。C# - 什麼是ADO.NET的一些高性能最佳實踐/技巧

+0

什麼數據庫(我假設SQL Server)? – MusiGenesis 2009-08-28 23:57:09

+0

我會避免過早優化。 – Alex 2009-08-29 00:15:30

+6

+1使用*普通老* ADO.NET :) – 2009-08-29 00:32:11

回答

9

一個錯誤我看到重複了一遍又一遍:

實例化和建立它在一個緊湊的循環反覆調用方法中的一切(的DbConnection,DbCommand和,DbParameters)。

大多數情況下,您可以重構這些局部變量作爲類成員實例化它們只有一次,只保留方法內的DbParameters的更新。


更新,包括在評論

免責聲明要求的示例代碼: 這是展示有關移動重複的東西圈外點的唯一目的的快速組裝樣品。 其他更好的做法不一定實施。


     public static void Show() { 
      List people = new List(); 

      //Everything is done inside the loop 
      PersonDal personDal = new PersonDal(); 
      foreach (Person person in people) { 
       personDal.Insert(person); 
      } 

      //Things are setup once outside the loop. 
      using (DbConnection connection = SqlClientFactory.Instance.CreateConnection()) { 
       // setup the connection 
       BetterPersonDal betterPersonDal = new BetterPersonDal(connection); 
       connection.Open(); 
       foreach (Person person in people) { 
        betterPersonDal.Insert(person); 
       } 
      } 
     } 
    } 

    class Person { 
     public int Id { get; set; } 
     public string Name { get; set; } 
    } 

在此先執行,每一件事情是建立在每次調用方法時:


class PersonDal { 
    public int Insert(Person person) { 
     DbProviderFactory factory = SqlClientFactory.Instance; 

     using (DbConnection connection = factory.CreateConnection()) { 
      connection.Open(); 

      connection.ConnectionString = "Whatever"; 

      using (DbCommand command = connection.CreateCommand()) { 
       command.CommandText = "Whatever"; 
       command.CommandType = CommandType.StoredProcedure; 

       DbParameter id = command.CreateParameter(); 
       id.ParameterName = "@Id"; 
       id.DbType = DbType.Int32; 
       id.Value = person.Id; 

       DbParameter name = command.CreateParameter(); 
       name.ParameterName = "@Name"; 
       name.DbType = DbType.String; 
       name.Size = 50; 
       name.Value = person.Name; 

       command.Parameters.AddRange(new DbParameter[] { id, name }); 

       return (int)command.ExecuteScalar(); 
      } 
     } 
    } 
} 

現在我們繼續設置到對象的建設留出循環:


class BetterPersonDal { 
    private DbProviderFactory factory; 
    private DbConnection connection; 
    private DbCommand command; 
    private DbParameter id; 
    private DbParameter name; 

    public BetterPersonDal(DbConnection connection) { 
     this.command = connection.CreateCommand(); 
     this.command.CommandText = "Whatever"; 
     this.command.CommandType = CommandType.StoredProcedure; 

     this.id = command.CreateParameter(); 
     this.id.ParameterName = "@Id"; 
     this.id.DbType = DbType.Int32; 

     this.name = command.CreateParameter(); 
     this.name.ParameterName = "@Name"; 
     this.name.DbType = DbType.String; 
     this.name.Size = 50; 

     this.command.Parameters.AddRange(new DbParameter[] { id, name }); 
    } 

    public int Insert(Person person) { 
     this.id.Value = person.Id; 
     this.name.Value = person.Name; 

     return (int)command.ExecuteScalar(); 
    } 
} 

+0

包含的示例 – 2009-08-29 01:49:24

4

查看Improving .NET Application Performance and Scalability書(可在線免費閱讀,在MSDN中)。有關於提高ADO.NET性能的whole chapter

+0

優秀的鏈接。我唯一不同意的是他們強調使用存儲過程來提高性能。據我瞭解,現代版本的SQL Server緩存臨時SQL查詢的執行計劃,所以在臨時查詢運行一次後,它應該像存儲過程一樣快。但是,鏈接的文章實際上來自微軟,所以我不會聲稱我比他們更瞭解。然而,在我最近所做的所有基準測試中,存儲過程和即席查詢的性能幾乎完全相同。 – MusiGenesis 2009-08-29 00:07:09

+1

的確是一本很好的書。我有它的印刷版。不幸的是,它自2004年以來一直沒有更新,很多東西已經改變。例如,DataRow的後備存儲在.Net 2.0中完全重寫,這極大地改變了在1.x和2.0之間使用DataSet的性能特徵。 – 2009-08-29 00:46:55

2

約連接管理非常聰明。打開數據庫連接可能非常昂貴,因此在編寫數據庫訪問層時請牢記這一點。

+4

只要啓用連接池,這應該不是問題。實例化一個連接對象並調用它的'Open'方法通常只是從池中獲取一個可用連接,而不是建立一個到數據庫的全新連接。 – LukeH 2009-08-28 23:42:38

+2

同意盧克。連接十多年來一直不值得擔心(很多)。 – MusiGenesis 2009-08-28 23:56:35

+0

我得到了一個用VB.Net編寫的遺留代碼,其中每個混合的東西都像是在VB6中編寫的一樣:沒有圖層,沒有類,表單和bas模塊中的所有代碼... – 2009-08-29 02:05:22

1

如果你不打算使用ORM,你是否也不會緩存你的數據?這是使用ORM的一大優勢。如果沒有數據緩存,則需要查看緩存HTML/JavaScript的方法。這可以使用OutputCache指令和SqlDependency完成。或者通過發佈靜態HTML和JavaScript文件。無論哪種方式,如果您不是每次請求都經常訪問數據庫,您將能夠處理更高的負載。

一些鏈接:

ASP.NET網站績效改進 http://www.codeproject.com/KB/aspnet/aspnetPerformance.aspx

10 ASP.NET性能和可擴展性的祕密 http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx

在ASP.NET AJAX和.NET

奧馬爾·Zabir博客3.5 http://msmvps.com/blogs/omar/archive/tags/performance/default.aspx

1

馬丁連接的文章非常好。我只是補充說,你一定要使用DataReader而不是DataSet(我喜歡DataSet,但不是出於性能的原因)。

+0

除非你必須回到在這種情況下使用DataSet的先前記錄可能是一個好主意。 – 2009-08-29 00:42:50

+0

@Alfred:他說他「希望頁面以高速加載」,所以我假設他正在談論ASP.Net。在這種情況下,讓用戶回到DataSet中的以前的記錄意味着緩存DataSet,這可能不是一個好主意。 – MusiGenesis 2009-08-29 00:53:01

+0

@MusiGenesis:我不是不同意你。你說過你喜歡DataSets,我正在舉例說明他們什麼時候適合。 即使在* super duper *高速網頁上,無論出於何種商業原因,都可能有人需要訪問以前的記錄。而不是回到數據庫,使用數據集。緩存中沒有DataSet - 沒有任何內容。只是在請求的生命週期中使用了一個DataSet。 – 2009-08-29 01:56:40

相關問題