对于具有双主键

时间:2015-07-27 09:14:37

标签: sql database performance ms-access

我有一个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

1 个答案:

答案 0 :(得分:0)

首先,您没有两个主键,只有两个非唯一索引。

要拥有主键,请添加包含自动编号的字段,或创建字段DateRisknumber的复合索引,并将其标记为主要

其次,您应该能够将Excel工作表附加(链接)为Access中的表并运行如下查询:

INSERT INTO 
    LoanTable
    ([Date], RiskNumber, CustomerName, RiskAmount)
SELECT
    [Date], RiskNumber, CustomerName, RiskAmount
FROM 
    LinkedExcelTable

每天一次。