diff options
author | Robert Haas <rhaas@postgresql.org> | 2015-12-23 14:06:52 -0500 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2015-12-23 14:06:52 -0500 |
commit | bc7fcab5e36b9597857fa7e3fa6d9ba54aaea167 (patch) | |
tree | f4ad237cbb7a2e9dd153bbe02444c8812cc51de8 /src | |
parent | 51d152f18e124cc07c293756cc16014ba218b2df (diff) | |
download | postgresql-bc7fcab5e36b9597857fa7e3fa6d9ba54aaea167.tar.gz postgresql-bc7fcab5e36b9597857fa7e3fa6d9ba54aaea167.zip |
Read from the same worker repeatedly until it returns no tuple.
The original coding read tuples from workers in round-robin fashion,
but performance testing shows that it works much better to read enough
to empty one queue before moving on to the next. I believe the
reason for this is that, with the old approach, we could easily wake
up a worker repeatedly to write only one new tuple into the shm_mq
each time. With this approach, by the time the process gets scheduled,
it has a decent chance of being able to fill the entire buffer in
one go.
Patch by me. Dilip Kumar helped with performance testing.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/executor/nodeGather.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c index f32da1e2352..db5883d28ef 100644 --- a/src/backend/executor/nodeGather.c +++ b/src/backend/executor/nodeGather.c @@ -359,14 +359,20 @@ gather_readnext(GatherState *gatherstate) continue; } - /* Advance nextreader pointer in round-robin fashion. */ - gatherstate->nextreader = - (gatherstate->nextreader + 1) % gatherstate->nreaders; - /* If we got a tuple, return it. */ if (tup) return tup; + /* + * Advance nextreader pointer in round-robin fashion. Note that we + * only reach this code if we weren't able to get a tuple from the + * current worker. We used to advance the nextreader pointer after + * every tuple, but it turns out to be much more efficient to keep + * reading from the same queue until that would require blocking. + */ + gatherstate->nextreader = + (gatherstate->nextreader + 1) % gatherstate->nreaders; + /* Have we visited every TupleQueueReader? */ if (gatherstate->nextreader == waitpos) { |