1

私は、それぞれ約 200,000 行を含む 12 のデータ テーブルを含む Access データベースを受け取りました。これらの各テーブルには、約 200 棟の建物に関する月次データが含まれています。データベースの正規化に多くの時間を費やしたくないので、このデータから各建物のテーブルを作成する簡単なスクリプトを書きました。

とはいえ、私のコードの実行には約 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
4

1 に答える 1

1

rstBuildNames.Fields("BuildingPath")そのコードは削除され、同じ構造で再作成されます。テーブルを空にする方が速いはずです:

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

ただし、これでは操作の速度が十分に向上しない可能性があります。

クエリのWHERE句はINSERT、完全なテーブル スキャンを強制します ...

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

Like比較の代わりに正確な文字列一致を使用して、 にインデックスを作成できればBuildingPath、大幅な改善が見られるはずです。

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

dbOpenSnapshotレコードセットを 1 回しか開いていないため、顕著な違いはありませんが、私もお勧めします。(役に立たないかもしれませんが、害はありません。)

Set rstBuildNames = RRRdb.OpenRecordset("BuildingNames", dbOpenSnapshot)
Set rstDataTables = RRRdb.OpenRecordset("DataTables", dbOpenSnapshot)
于 2013-08-01T21:12:37.800 に答える