我有一个MS Access数据库表,其中包含超过500000条记录。
表结构如下:
| ReportDate (Date/Time) | RiskNumber (Decimal) | CustomerName (String) | RiskAmount (Currency) |
| 24.07.2015 | 1234567891011 | Donald Duck | $987,654.00 |
| 24.07.2015 | 9876543210987 | Bugs Bunny | $456,456.00 |
| ... | ... | ... | ... |
| ... | ... | ... | ... |
| 23.07.2015 | 1234567891011 | Donald Duck | $987,456.00 |
| 23.07.2015 | 9876543210987 | Bugs Bunny | $456,123.00 |
| ... | ... | ... | ... |
| ... | ... | ... | ... |
该表格有两个主键,分别为 ReportDate 和 RiskNumber 。
两个主键都被索引,允许重复。
每天约有2500个条目被添加到表格中,并带有相应的日期值 对于特定的一天,没有重复的RiskNumber。
每天,在Excel中使用Visual Basic代码,我从一个大的Excel文件中读取今天的值并将它们插入到数据库表中。在此之前,代码检查昨天的RiskAmount值以在另一个日志表中创建日志记录。
数据库更新由使用Interface的用户(具有非常基本的IT知识)启动。他/她选择源Excel文件,其余部分由Visual Basic代码处理。
这些是Visual Basic生成的查询:
SELECT TOP 1 RiskAmount FROM LoanTable WHERE (RiskNumber=1234567891011 AND ReportDate=#2015-07-23#);
INSERT INTO LoanTable (ReportDate, RiskNumber, CustomerName, RiskAmount) VALUES ('24.07.2015', 1234567891011, 'Donald Duck', 987456)
所以,问题是,选择查询需要大约1秒才能执行,整个表需要大约40分钟才能更新。
如何优化此表和查询以加快速度?
编辑:这是DatabaseUtility类的GetCellFromAccess函数:
Function GetCellFromAccess(theCriteriaValue As Variant, _
Optional theCriteriaField As String = "RiskNumber", _
Optional theSelectionField As String = "Nothing") As Variant
On Error GoTo ErrorHandler
Dim SqlStr As String
Dim cellValue As Variant
Dim theCriteriaValues As New Collection
Dim theCriteriaFields As New Collection
Dim theSelectionFields As New Collection
If Not pDateString = "Nothing" Then
theCriteriaValues.Add pDateString
theCriteriaFields.Add "ReportDate"
End If
theCriteriaValues.Add theCriteriaValue
theCriteriaFields.Add theCriteriaField
If Not theSelectionField = "Nothing" Then
theSelectionFields.Add theSelectionField
Else
theSelectionFields.Add currentField
End If
'This is the select query Generator, no Problem here
'Output example: "SELECT TOP 1 RiskAmount FROM LoanTable WHERE (RiskNumber=1234567891011 AND ReportDate=#2015-07-23#);"
SqlStr = SelectQuery(theCriteriaValues, theCriteriaFields, theSelectionFields, , 1)
cmd.CommandText = SqlStr
Set rs = cmd.Execute
If rs.EOF = True Then
cellValue = "NOTINDB"
ElseIf rs.fields(0) = Null Then
cellValue = ""
Else
cellValue = rs.fields(0).Value
End If
GetCellFromAccess = cellValue
Exit Function
ErrorHandler:
GetCellFromAccess = "Failure"
End Function
代码中最慢的部分是:
Set rs = cmd.Execute
答案 0 :(得分:0)
首先,您没有两个主键,只有两个非唯一索引。
要拥有主键,请添加包含自动编号的字段,或创建字段Date
和Risknumber
的复合索引,并将其标记为主要
其次,您应该能够将Excel工作表附加(链接)为Access中的表并运行如下查询:
INSERT INTO
LoanTable
([Date], RiskNumber, CustomerName, RiskAmount)
SELECT
[Date], RiskNumber, CustomerName, RiskAmount
FROM
LinkedExcelTable
每天一次。