2017-04-20 111 views
0

我有一个相当缓慢的查询:的MS Access - 速度问题

SELECT ticketnumber, stateactual, adj, 
    ConcatRelated("utilityname","IntTable","ticketnumber = """ & ticketnumber & """" & " AND " & "stateactual = """ & stateactual & """") AS utilities, 
    ConcatRelated("startupcustomer","IntTable","ticketnumber = """ & ticketnumber & """" & " AND " & "stateactual = """ & stateactual & """") as startdates 
INTO tixconcat 
FROM IntTable 
WHERE stateactual = "MT" 
GROUP BY ticketnumber, stateactual, adj; 

我用这个绅士的concatrelated查询:

http://allenbrowne.com/func-concat.html

这完美的作品 - 但它真的很慢。就像,每秒一个记录。我试图在110万条记录上运行这个记录,我真的需要在下次选举之前完成。有任何想法吗?

我已经压缩并修复了数据库。

谢谢!

+0

反规格化数据确实有其缺点。您的数据是在本地计算机上还是通过网络访问服务器?本地数据可能会稍微快一点,但我怀疑这足够了。 – June7

+0

ConcatRelated看起来像一个UDF(用户定义的函数),它是速度问题的主要原因。 UDF是转换数据的非常灵活的方式,但在具有数十万或数百万行的查询中使用它们总是会很慢。 – Sorcefyre

+0

在[IntTable]表中[ticketnumber]和[stateactual]字段是否有索引? –

回答

0

需要时间的主要事情是ConcatRelated函数。它打开一个表格,搜索它,给出结果,然后每行关闭表格两次。如果您希望快速完成此过程,则需要使用SQL而不是用户定义的函数来对数据进行非规范化。

要连接您的字段,这是我用来使其更快的过程。

步骤1 使用交叉表查询来获取要在1行上连接的字段。用你的外键行标题,和你想连接的两列标题和值

步骤2 串联列要从交叉表查询

步骤3制作以连接东西您的最终查询并加入第2步中的查询的查询/结果

您需要使用5个查询(每个并置字段的步骤1和2),但它仍然会比您所做的更快现在。请注意,您可以在步骤1中

结果可能会略有不同已经过滤,因为ConcatRelated可以Concat的相同值的两倍,而我的方法不会

+0

我遵循。我有1100个外键。最终产品中的任何一行都不会超过一打。你认为它会与许多专栏一起工作吗?我可能不得不完全重新考虑我的方法。 –

1

一个人在建议索引的字段的意见。这工作 - 在一个小时内运行整个查询:)

0

正如其他人所指出的那样,它并没有为每一行调用函数(这是昂贵的)。但是,加载sql字符串,加载查询处理器,检查SQL语法和THEN JET/ACE必须构建查询计划,然后打开表,然后执行查询就是成本所在。

我会建议旁路查询处理器,并在查询开始时直接打开表“一次”。因此,这意味着使用seek()命令,因为它会直接命中索引并通过sql。在使用“静态”上述

Public Function MyCon(vPK As Variant) As String 

    Static rst As DAO.Recordset 
    Static db As DAO.Database 
    Dim strV As String 
    Dim bolF As Boolean 
    'Stop 
    If rst Is Nothing Then 
    Set db = CurrentDb 
    Set rst = db.OpenRecordset("tblChild") 
    End If 

    With rst 
    .Index = "main_id" 
    .MoveFirst 
    .Seek "=", vPK 

    bolF = Not (.NoMatch) 
    Do While bolF 
     If MyCon <> "" Then MyCon = MyCon & "," 
     MyCon = MyCon & rst!InvoiceNumber 
     .MoveNext 
     If .EOF = True Then 
      bolF = False 
     Else 
      bolF = rst!main_id = vPK 
     End If 
    Loop 
    End With 


End Function 

注意 - 这意味着该变量保持其价值 - 我们因此只打开表一次:

此代码应运行速度快约1000倍。