An update query takes very long time (1 Viewer)

isladogs

MVP / VIP
Local time
Today, 01:12
Joined
Jan 14, 2017
Messages
18,221
jdraw/mark

Just to confirm, the OP did say all fields were numbers.
He also said there were about 10000 records in the reference table used for the update (tblList) but up to a million records in all (presumably in tblFinal)

Therefore whilst I agree that there is nothing in this code to prevent updates being repeated unnecessarily, the suggested query should do the job ...once PK fields have been assigned ... and indexing added

Code:
UPDATE tblFinal INNER JOIN tblList ON tblFinal.Type = tblList.Range SET tblFinal.Customer = tblList.Customer
WHERE (((tblFinal.CodeNumber) Between [tblList].[StartRange] And [tblList].[EndRange]));
 

jdraw

Super Moderator
Staff member
Local time
Yesterday, 20:12
Joined
Jan 23, 2006
Messages
15,379
Mark,Colin

I agree that 1 record per Customer seems sufficient. That's where I was heading when I said there may be ways to reduce the number of updates. But more info on the application would clarify things.
It's hard to guess what the issue really is when the OP has said there are no PKs, and indexes.
I agree Colin that the query should work even if there are multiple updates of same values on same records.
We are trying to assist in optimizing something that may be based on a poor data structure. Or, said differently, a few changes in data structure may eliminate the underlying issue of speed(or lack thereof).
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Yesterday, 19:12
Joined
Feb 28, 2001
Messages
27,184
Colin, I believe you have the idea when talking about repeated updating of the same records, but I'll restate it using my way of looking at it.

I wonder if what we have here is the moral equivalent of a Cartesian Join. It might be instructive if that query could be run using <dao-database>.Execute and then check for the number of records affected. The OP claims about 10,000 records. If the answer isn't 10,000 but is more like 10,000,000 or maybe 1 billion, then some Cartesian Join action is going on here. That would CERTAINLY explain why it takes so much time.

The OP says there are no indexes, which I believe has to mean there are also no PKs anywhere. He also claims a 1:1 JOIN, which I suppose is possible, but if there are no PKs, there can be no relationships. Which means that to perform the JOIN, Access has to do a double-barreled relation scan with unpredictable table orders. This problem SCREAMS for indexing the joined fields from both tables if nothing else.
 
Last edited:

Pat Hartman

Super Moderator
Staff member
Local time
Yesterday, 20:12
Joined
Feb 19, 2002
Messages
43,275
To find out how many updates are actually happening. Change the update query to a select query and look at the number of rows returned. If it is extremely large, that is the problem and we need to look for a way to reduce the number of times each record is updated.
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 08:12
Joined
May 7, 2009
Messages
19,242
forgot to add the other criteria, also not sure if number or date you are filtering
between startRange and EndRange:
Code:
Public Function fncUpdateTBLFinal()

    Const TARGET_TABLE As String = "tblFinal"
    Const SOURCE_TABLE As String = "tblList"
    
    Dim rsTarget    As DAO.Recordset
    Dim rsSource    As DAO.Recordset
    Dim qd          As DAO.QueryDef
    Dim db          As DAO.Database
    
    Set db = CurrentDb
    Set rsTarget = db.OpenRecordset(TARGET_TABLE, dbOpenDynaset)
    With rsTarget
        If Not (.BOF And .EOF) Then .MoveFirst
        While Not .EOF
            Set qd = db.CreateQueryDef(vbNullString, _
                        "SELECT Customer FROM " & SOURCE_TABLE & " " & _
                        "WHERE (Range = p1) And (p2 " & _
                        "BETWEEN [StartRange] AND [EndRange]);")
            qd.Parameters(0).Value = !Type.Value
            qd.Parameters(1).Value = !CodeNumber.Value
            Set rsSource = qd.OpenRecordset(dbOpenSnapshot)
            If Not (rsSource.BOF And rsSource.EOF) Then
                rsSource.MoveFirst
                .Edit
                !Customer = rsSource(0)
                .Update
            End If
            rsSource.Close
            Set rsSource = Nothing
            Set qd = Nothing
            DoEvents
            .MoveNext
        Wend
        .Close
    End With
    Set rsTarget = Nothing
    Set db = Nothing
End Function
 

Users who are viewing this thread

Top Bottom