2013-02-04 193 views
0

該功能需要約1.2秒的時間才能執行。我無法理解爲什麼?是因爲內部聯接嗎?如果是,那我該如何提高執行速度?我正在使用Microsoft企業庫。如何提高此功能的性能?

Public Shared Function GetDataByInterests(ByVal accountId As Integer) As Object 


      Dim details As New List(Of GetIdBasedOnInterest)() 
      Dim getIDs As New GetIdBasedOnInterest 

      Dim interests As String = "" 

      Dim db As SqlDatabase = Connection.Connection 


      Using cmdGeneric As DbCommand = db.GetSqlStringCommand("SELECT Interests.InterestName FROM UserInterests INNER JOIN Interests ON UserInterests.InterestID = Interests.InterestID WHERE [email protected]") 
       db.AddInParameter(cmdGeneric, "AccountID", SqlDbType.Int, accountId) 
       Dim dsInterests As DataSet = db.ExecuteDataSet(cmdGeneric) 
       For i = 0 To dsInterests.Tables(0).Rows.Count - 1 
        If i = dsInterests.Tables(0).Rows.Count - 1 Then 
         interests = interests & dsInterests.Tables(0).Rows(i).Item(0).ToString 
        Else 
         interests = interests & dsInterests.Tables(0).Rows(i).Item(0).ToString & "," 
        End If 
       Next 
      End Using 
    getIDs.InterestName = interests 
      details.Add(getIDs) 

      Return details 
     End Function 
+1

您必須先跟蹤並查看您的sql服務器上的選擇命令的速度。 – Aristos

+0

我該怎麼做? – Monodeep

+0

在SSMS中爲典型的accountID運行SQL。需要多長時間(您可以選擇前後查看的當前日期/時間戳)?這將表明時間是用在SQL還是VB代碼中。 InterestID是否被索引在兩個表上(即被定義爲索引還是主鍵)?如果不是,那麼如果表格很大,這會減慢查詢速度。 – NigelK

回答

1

不知道底層表及其索引(這是一個檢查,你應該馬上做的)有在循環一個明顯的問題的東西。
你可以連字符串,這可能會對程序使用的內存造成很大的壓力。
字符串連接導致在內存中分配一個新字符串,因此,如果您的表包含很多行,則效果可能很明顯。

你可以嘗試使用StringBuilder

Dim interests As new StringBuilder(1024) ' suppose an internal buffer of 1K' 
... 

If i = dsInterests.Tables(0).Rows.Count - 1 Then 
    interests.Append(dsInterests.Tables(0).Rows(i).Item(0).ToString) 
Else 
    interests.Append(dsInterests.Tables(0).Rows(i).Item(0).ToString & ",") 
End If 

.... 

getIDs.InterestName = interests.ToString 

當然,如果你的表(UserInterestsInterests)不上的字段正確索引這種優化可能是絕對不重要InterestIDAccountID

編輯:另一個微觀優化是刪除內部中頻測試,並截斷結果輸出只有在循環結束後

For .... 
    interests.Append(dsInterests.Tables(0).Rows(i).Item(0).ToString & ",") 
Next 
if(interest.Length > 0) interest.Length -= 1; 

編輯至於你的請求,這是一個創建一個唯一索引的例子。語法可能更加複雜和變化的根據SQL Server版本,但基本上你在SQL Management Studio中

CREATE UNIQUE INDEX <indexname> ON <tablename> 
(
    <columntobeindexed> 
) 

做檢查CREATE INDEX聲明的例子在MSDN上

+0

'InterestID'和'AccountID'是自動增量整數,即'Identity'。那麼,我是否還需要對它們進行「索引」。如果是這樣如何?不是Sql Server自動索引它們嗎? – Monodeep

+1

「索引」和「標識」列不是一回事。如果您的系統需要唯一性,您至少應該在標識列上放置唯一的索引。並且標識列不保證唯一性(SET IDENTITY_INSERT

開啓/關閉) – Steve

+0

如何索引標識列? – Monodeep

1

1)時間查詢的SQL Server管理工作室。將它與VB代碼隔離很容易。你也可以運行查詢計劃,甚至可以建議新的索引。

2)檢查您是否定義了相關的主鍵和索引。

3)拉共同表達出你的for循環,避免一遍又一遍地計算相同的事情:

4)像史蒂夫說,使用StringBuilder

結合這幾點:

  Dim theTable as ... 
      Dim rowCount as Integer 
      Dim interests As new StringBuilder(1024) 
      Set theTable = dsInterests.Tables(0) 
      rowCount = theTable.Rows.Count 
      For i = 0 To rowCount - 1 
       interests.Append(theTable.Rows(i).Item(0).ToString) 
       If i <> rowCount - 1 Then 
        interests.Append(",") 
       End If 
      Next