2013-12-09 43 views
1

所以我得到了一個非常大的表,裏面有大約22 MIO行..我婉他們都加載到vb.net應用程序內存(我得到的36GB RAM,所以我應該沒問題)。裝入一個非常大的表從MSSQL到vb.net內存

現在爲連接不超時,我想要求加載一個大表的最佳方式。

,如果有要反饋給應用程序,在這個過程中,因爲它可能需要幾分鐘時間做的一種方式。

我normaly使用SqlDataReader的..但是,還好那個大量數據的使用?

我嘗試了一些關於這個問題的搜索引擎。我把整個表加載到內存中的原因是要更快地分析它,因爲我需要運行一些正則表達式,並對它進行排序,而不是TSQL提供。

我希望有人能幫助,因爲我有點這個

+0

什麼意思_into memory_?你想填寫一個'List '或一個'DataTable'或者其他什麼? –

+1

您可以通過10000 加載一樣使用MYSQL的LIMIT命令和處理行10000列第一與LIMIT 0,10000選擇,然後LIMIT 10000,10000等 並優化的東西,你可以在一個線程啓動取當你處理先前提取的10000行的正則表達式 –

+0

我正在考慮將它加載到任何數組(List,DataTable或事件數組)中,這是最浪費的運行槽。它的proberly數據表,以保持結構完好無損。 – Droa

回答

1

卡應使用ROW_NUMBER到巨大的結果集劃分成更小的塊。然後你可以報告每個塊的進度。因此,您可以使用BackGroundWorker來更新Label和/或ProgressBar。要確定每個組的大小,您可以先選擇total-rowcount。 (下面的示例中1000)使用此作爲除數爲的CHUNKSIZE:

這裏是填補了DataTable和使用LINQ選擇從特里結果只有小團體工作的方法:

上的開關按鈕,點擊開始所述BackGroundWorker

Private Sub SomeButton_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click 
    Me.BackgroundWorker1.RunWorkerAsync() 
End Sub 

處理的DoWork事件加載數據:

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork 
    Dim tblData As New DataTable() 
    Dim totalCount = 0 
    Dim chunkSize As Int32 = 1000 
    Dim countSQL = "SELECT COUNT(*) FROM dbo.tabData" 
    Dim dataSql = "WITH CTE AS(SELECT d.*, rn=ROW_NUMBER()OVER(ORDER BY d.idData) FROM dbo.tabData d) SELECT * FROM CTE WHERE RN BETWEEN @RowStart AND @RowEnd;" 
    Using con As New SqlConnection(My.Settings.ConnectionString) 
     Using cmdCount = New SqlCommand(countSQL, con) 
      con.Open() 
      totalCount = DirectCast(cmdCount.ExecuteScalar, Integer) 
     End Using 
     Dim chunks = Enumerable.Range(0, totalCount). 
      GroupBy(Function(i) i \ chunkSize). 
      Select(Function(grp, index) New With { 
         .RowStart = grp.Min() + 1, 
         .RowEnd = grp.Max() + 1, 
         .GroupNum = index + 1 
        }) 
     For Each chunk In chunks 
      Using cmdData = New SqlCommand(dataSql, con) 
       cmdData.Parameters.AddWithValue("@RowStart", chunk.RowStart) 
       cmdData.Parameters.AddWithValue("@RowEnd", chunk.RowEnd) 
       Using da = New SqlDataAdapter(cmdData) 
        da.Fill(tblData) 
        BackgroundWorker1.ReportProgress(Math.Ceiling(chunk.GroupNum * chunkSize/totalCount)) 
       End Using 
      End Using 
     Next 
     BackgroundWorker1.ReportProgress(100) ' all data loaded ' 
    End Using 
End Sub 

更新標籤和/或在每塊終於ProgressBar

Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged 
    Me.ProgressLabel.Text = e.ProgressPercentage & " Percent loaded" 
    Me.ProgressBar1.Value = e.ProgressPercentage 
End Sub 

Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted 
    Me.ProgressLabel.Text = "100 Percent loaded. Finished." 
End Sub 
+0

非常感謝,這是好得多,然後我想出了我自己,我做很多方法:) – Droa

+0

我似乎有一些問題加載SQL ..它需要約每5千行1000分鐘,我想代碼是太重,所有thouse行:( – Droa

+0

@Droa:你用什麼專欄來訂購,PK專欄?我用一個有1500萬條記錄的表對上面的代碼進行了測試,直到DataTable包含100萬行並花了5分鐘。 –

相關問題