Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b246510

Browse files
committed
Avoid O(N^2) behavior in deferredTriggerAddEvent() for large numbers of
tuples inserted/deleted/updated in a single transaction. On my machine, this reduced the time to delete 80000 tuples in a foreign-key-referencing table from ~15min to ~8sec.
1 parent 74c732c commit b246510

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

src/backend/commands/trigger.c

+23-8
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.86 2001/01/27 05:16:58 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.87 2001/03/12 23:02:00 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1152,14 +1152,16 @@ static bool deftrig_all_isdeferred;
11521152
static List *deftrig_trigstates;
11531153

11541154
/* ----------
1155-
* The list of events during the entire transaction.
1155+
* The list of events during the entire transaction. deftrig_events
1156+
* is the head, deftrig_event_tail is the last entry.
11561157
*
1157-
* XXX This must finally be held in a file because of the huge
1158-
* number of events that could occur in the real world.
1158+
* XXX Need to be able to shove this data out to a file if it grows too
1159+
* large...
11591160
* ----------
11601161
*/
11611162
static int deftrig_n_events;
11621163
static List *deftrig_events;
1164+
static List *deftrig_event_tail;
11631165

11641166

11651167
/* ----------
@@ -1235,7 +1237,22 @@ deferredTriggerCheckState(Oid tgoid, int32 itemstate)
12351237
static void
12361238
deferredTriggerAddEvent(DeferredTriggerEvent event)
12371239
{
1238-
deftrig_events = lappend(deftrig_events, event);
1240+
/*
1241+
* Since the event list could grow quite long, we keep track of the
1242+
* list tail and append there, rather than just doing a stupid "lappend".
1243+
* This avoids O(N^2) behavior for large numbers of events.
1244+
*/
1245+
if (deftrig_event_tail == NIL)
1246+
{
1247+
/* first list entry */
1248+
deftrig_events = makeList1(event);
1249+
deftrig_event_tail = deftrig_events;
1250+
}
1251+
else
1252+
{
1253+
lnext(deftrig_event_tail) = makeList1(event);
1254+
deftrig_event_tail = lnext(deftrig_event_tail);
1255+
}
12391256
deftrig_n_events++;
12401257
}
12411258

@@ -1397,7 +1414,6 @@ deferredTriggerInvokeEvents(bool immediate_only)
13971414
List *el;
13981415
DeferredTriggerEvent event;
13991416
int still_deferred_ones;
1400-
int eventno = -1;
14011417
int i;
14021418
MemoryContext per_tuple_context;
14031419

@@ -1421,8 +1437,6 @@ deferredTriggerInvokeEvents(bool immediate_only)
14211437

14221438
foreach(el, deftrig_events)
14231439
{
1424-
eventno++;
1425-
14261440
MemoryContextReset(per_tuple_context);
14271441

14281442
/* ----------
@@ -1548,6 +1562,7 @@ DeferredTriggerBeginXact(void)
15481562

15491563
deftrig_n_events = 0;
15501564
deftrig_events = NIL;
1565+
deftrig_event_tail = NIL;
15511566
}
15521567

15531568

0 commit comments

Comments
 (0)