为什么这个访问查询需要这么久?

我写了一个访问客户端来比较两个excel文件。 它将正在比较的两个excel文件加载到临时表中,并根据下面显示的两个查询对它们进行评估。

有两个查询,因为有时Excel文件中只有一个名称列。 基本上用户input被比较的列的名称,我们改变基于这个的查询。

第一个查询, cQueryFull ,完美,非常快速(超过10万logging在几秒钟内)。 第二个查询cQueryPart按照预期工作(按照比较),但从未在超过5,000个logging的表上完成。 结果挂了几个小时,我被迫closures了这个程序。

我不明白为什么一个查询比另一个查询快得多,我希望有人能够帮我弄清楚,并可能修复第二个查询。 我创build查询的访问客户端部分如下:

 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 

任何人都可以识别我的查询问题? 万一它很重要,我已经试图build立和执行查询之前索引表。 任何帮助将不胜感激!

这很难说,但我怀疑问题是在交叉连接和WHERE子句中的谓词(和谓词的types)的数量。

像你在做的那样连接两个表往往会创build一个非常大的集合,WHERE子句将不得不通过。 而且,JET / ACE查询中的LIKE运算符可能是最慢的比较运算符。 尤其是像领先的通配符(*)。

有时候没有办法解决这个问题,但是有时把预先查询的部分加载到另外一个临时表中并且对这些数据运行更多的查询会更快。

有没有什么办法可以简化你的WHERE子句,或者在不同的批次中标识谓词,这样你可以先运行一个更直接的查询,然后进一步处理这些结果呢? (我build议可能写入临时表和进一步的查询,因为子查询是优化的,并不一定保证你所写的“sql逻辑”将是如何实际运行)。