2013-08-01 16 views
1

我給了一個Access數據庫,其中包括12個數據表,每個數據表包含大約200,000行。每個表格都包含約200座建築物的月度數據。我不想花太多時間正常化數據庫,我只是寫了一個快速腳本,從這些數據爲每個建築物創建一個表格。Access 2007 VBA - 大型數據集 - 如何優化此查詢/代碼?

說了這麼多,我的代碼需要大約1.5小時才能運行。有什麼我可以做的,以加快速度,或者我只是達到Access的能力極限?任何建議將不勝感激。

Sub RunQueryForEachBuilding() 

Dim RRRdb As DAO.Database 
Dim rstBuildNames As DAO.Recordset 
Dim rstDataTables As DAO.Recordset 
Dim rstMonthlyData As DAO.Recordset 
Dim strSQL As String 
Dim sqlCreateT As String 
Dim sqlBuildData As String 
Dim strDataTable As String 
Dim sqlDrop As String 


On Error GoTo ErrorHandler 
'open recordsets for building names and datatables 
Set RRRdb = CurrentDb 
Set rstBuildNames = RRRdb.OpenRecordset("BuildingNames") 
Set rstDataTables = RRRdb.OpenRecordset("DataTables") 

Do Until rstBuildNames.EOF 
    ' Create a table for each building. 
    ' Check if table exists, if it does delete and recreate. 

    If Not IsNull(DLookup("Name", "MSysObjects", "Name='" & rstBuildNames.Fields("BuildingPath") & "'")) Then 
     ' Table Exists - delete existing 
     sqlDrop = "DROP TABLE [" & rstBuildNames.Fields("BuildingPath") & "]" 

     RRRdb.Execute sqlDrop 
     ' re-create blank table 
    End If 
    'create table for this building 
    sqlCreateT = "CREATE TABLE [" & rstBuildNames.Fields("BuildingPath") & _ 
    "] (BuildingPath VARCHAR, [TimeStamp] DATETIME, CHWmmBTU DOUBLE , ElectricmmBTU DOUBLE, kW DOUBLE, kWSolar DOUBLE, kWh DOUBLE, kWhSolar DOUBLE)" 

    RRRdb.Execute sqlCreateT 

'populate data from monthly table into the building name table. 
Do While Not rstDataTables.EOF 
    ' get data from each monthly table for this building and APPEND to table. 
    strDataTable = rstDataTables.Fields("[Data Table]") 
    'Debug.Print strDataTable 
    'create a SQL string that only selects records that are for the correct building & inserts them into the building table 

    sqlBuildData = "INSERT INTO [" & rstBuildNames.Fields("BuildingPath") 
    sqlBuildData = sqlBuildData & "] ([TimeStamp], [CHWmmBTU], [ElectricmmBTU], kW, [kWSolar], kWh, [kWhSolar], BuildingPath) " 
    sqlBuildData = sqlBuildData & " SELECT [TimeStamp], [CHW mmBTU], [Electric mmBTU], kW, [kW Solar], kWh, [kWh Solar], BuildingPath FROM " 
    sqlBuildData = sqlBuildData & rstDataTables.Fields("[Data Table]") & " WHERE BuildingPath LIKE '*" & rstBuildNames.Fields("BuildingPath") & "'" 

    'Debug.Print sqlBuildData 

    RRRdb.Execute sqlBuildData 
    rstDataTables.MoveNext 

Loop 

rstBuildNames.MoveNext 
rstDataTables.MoveFirst 

Loop 

Set rstBuildNames = Nothing 
Set rstDataTables = Nothing 

ErrorHandler: 
'MsgBox "Error #: " & Err.Number & vbCrLf & vbCrLf & Err.Description 

End Sub 
+0

好的,謝謝我要試試這個。 – brl8

回答

1

該代碼下降,然後重新創建與rstBuildNames.Fields("BuildingPath")相同的結構。它應該是更快地只是空出表:

"DELETE FROM " & rstBuildNames.Fields("BuildingPath") 

當然,這是不可能足夠的加速操作。

INSERT查詢的WHERE條款強制執行全表掃描...

" WHERE BuildingPath LIKE '*" & rstBuildNames.Fields("BuildingPath") & "'" 

如果你可以使用一個確切的字符串匹配,而不是一個Like比較,並創建BuildingPath索引,你應該看到顯着的改善。

" WHERE BuildingPath = '" & rstBuildNames.Fields("BuildingPath") & "'" 

我會建議dbOpenSnapshot也一樣,即使它不會讓一個明顯的區別,因爲你只打開一個記錄集時。 (這可能沒有幫助,但它不會傷害。)

Set rstBuildNames = RRRdb.OpenRecordset("BuildingNames", dbOpenSnapshot) 
Set rstDataTables = RRRdb.OpenRecordset("DataTables", dbOpenSnapshot)