我写了一个访问客户端来对两个excel文件进行比较。它将两个要比较的excel文件加载到临时表中,并根据下面显示的两个查询对它们进行评估。
有两个查询,因为有时其中一个excel文件只有一个名称列。基本上,用户输入要比较的列的名称,我们会根据该列更改查询。
第一个查询cQueryFull
可以完美而快速地工作(仅需几秒钟即可完成超过100k的记录)。第二个查询cQueryPart
按预期工作(就比较而言),但从未在具有超过5,000条记录的表上完成。它最终挂了几个小时,我被迫关闭该程序。
我不明白为什么一个查询比另一个查询快得多,我希望有人能够帮助我解决它并可能修复第二个查询。我的访问客户端创建查询的部分如下:
If chkOneColumn.Value = 0 Then
' Construct Comparison Query
qString = "SELECT OriginalFile." & txtOriginalFirst.Value & " as OriginalFirstName, OriginalFile." & txtOriginalMiddle.Value & " as OriginalMiddleName, OriginalFile." & txtOriginalLast.Value & " as OriginalLastName, WorkingFile." & txtWorkingFirst.Value & " as WorkingFirstName, WorkingFile." & txtWorkingMiddle.Value & " as WorkingMiddleName, WorkingFile." & txtWorkingLast.Value & " as WorkingLastName " _
+ "FROM OriginalFile, WorkingFile " _
+ "WHERE (OriginalFile." & txtOriginalFirst.Value & " not like WorkingFile." & txtWorkingFirst.Value & " or OriginalFile." & txtOriginalMiddle.Value & " not like WorkingFile." & txtWorkingMiddle.Value & " or OriginalFile." & txtOriginalLast.Value & " not like WorkingFile." & txtWorkingLast.Value & ") " _
+ "and OriginalFile." & txtOriginalAddress.Value & " = WorkingFile." & txtWorkingAddress.Value & " " _
+ "and OriginalFile." & txtOriginalDOB.Value & " = WorkingFile." & txtWorkingDOB.Value & " "
' Open the record set
Set db = CurrentDb
Set qd = db.CreateQueryDef("cQueryFull")
With qd
.ReturnsRecords = True
.sql = qString
End With
DoCmd.OpenQuery "cQueryFull"
ElseIf chkOneColumn.Value = -1 Then
' Construct Comparison Query
qString = "SELECT OriginalFile." & txtOriginalFirst.Value & " as OriginalName, IIF(WorkingFile." & txtWorkingFirst.Value & " is null, '', WorkingFile." & txtWorkingFirst.Value & ") + IIF(WorkingFile." & txtWorkingMiddle.Value & " is null, '', ' '+WorkingFile." & txtWorkingMiddle.Value & ") + IIF(WorkingFile." & txtWorkingLast.Value & " is null, '', ' '+WorkingFile." & txtWorkingLast.Value & ") as WorkingName " _
+ "FROM OriginalFile, WorkingFile " _
+ "WHERE (OriginalFile." & txtOriginalFirst.Value & " not like '*'+WorkingFile." & txtWorkingFirst.Value & "+'*' or OriginalFile." & txtOriginalFirst.Value & " not like '*'+WorkingFile." & txtWorkingMiddle.Value & "+'*' or OriginalFile." & txtOriginalFirst.Value & " not like '*'+WorkingFile." & txtWorkingMiddle.Value & "+'*') " _
+ "and OriginalFile." & txtOriginalAddress.Value & " like WorkingFile." & txtWorkingAddress.Value + " " _
+ "and OriginalFile." & txtOriginalDOB.Value & " like WorkingFile." & txtWorkingDOB.Value & " " _
' Open the record set
Set db = CurrentDb
Set qd = db.CreateQueryDef("cQueryPart")
With qd
.ReturnsRecords = True
.sql = qString
End With
DoCmd.OpenQuery "cQueryPart"
End If
任何人都可以通过我的查询识别问题吗?如果它很重要,我已经尝试在构建和执行查询之前索引表。任何帮助将不胜感激!
答案 0 :(得分:1)
很难说,但我怀疑问题在于WHERE子句中的交叉连接和谓词量(以及谓词类型)。
像你一样加入两个表往往会创建一个非常大的集合,然后必须运行WHERE子句。此外,JET / ACE查询中的LIKE运算符可能是最慢的比较运算符。特别喜欢领先的通配符(*)。
有时候只是没有解决它,但有时将预先查询的部分加载到(另一个)临时表中并对该数据运行进一步的查询实际上更快。
有没有什么方法可以简化你的WHERE子句,或者以不同批次的方式识别谓词,以便你可以先运行更直接的查询,然后进一步处理这些结果? (我建议可能写入临时表并进一步查询,因为子查询已经过优化,并不一定能保证你编写的“sql逻辑”就像它实际运行的那样)。