Re: [HACKERS] [PATCH] Incremental sort
Alexander Korotkov <a.korotkov@postgrespro.ru>
Hi!
On Mon, Nov 20, 2017 at 12:24 AM, Thomas Munro <
thomas.munro@enterprisedb.com> wrote:
> On Wed, Nov 15, 2017 at 7:42 AM, Alexander Korotkov
> <a.korotkov@postgrespro.ru> wrote:
> > Sure, please find rebased patch attached.
>
> + /*
> + * Check if first "skipCols" sort values are equal.
> + */
> + static bool
> + cmpSortSkipCols(IncrementalSortState *node, TupleTableSlot *a,
> +
> TupleTableSlot *b)
> + {
> + int n, i;
> +
> + Assert(IsA(node->ss.ps.plan, IncrementalSort));
> +
> + n = ((IncrementalSort *) node->ss.ps.plan)->skipCols;
> +
> + for (i = 0; i < n; i++)
> + {
> + Datum datumA, datumB, result;
> + bool isnullA, isnullB;
> + AttrNumber attno = node->skipKeys[i].attno;
> + SkipKeyData *key;
> +
> + datumA = slot_getattr(a, attno, &isnullA);
> + datumB = slot_getattr(b, attno, &isnullB);
> +
> + /* Special case for NULL-vs-NULL, else use standard comparison */
> + if (isnullA || isnullB)
> + {
> + if (isnullA == isnullB)
> + continue;
> + else
> + return false;
> + }
> +
> + key = &node->skipKeys[i];
> +
> + key->fcinfo.arg[0] = datumA;
> + key->fcinfo.arg[1] = datumB;
> +
> + /* just for paranoia's sake, we reset isnull each time */
> + key->fcinfo.isnull = false;
> +
> + result = FunctionCallInvoke(&key->fcinfo);
> +
> + /* Check for null result, since caller is clearly not expecting
> one */
> + if (key->fcinfo.isnull)
> + elog(ERROR, "function %u returned NULL", key->flinfo.fn_oid);
> +
> + if (!DatumGetBool(result))
> + return false;
> + }
> + return true;
> + }
>
> Is there some reason not to use ApplySortComparator for this? I think
> you're missing out on lower-overhead comparators, and in any case it's
> probably good code reuse, no?
>
However, for incremental sort case we don't need to know here whether A > B
or B > A. It's enough for us to know if A = B or A != B. In some cases
it's way cheaper. For instance, for texts equality check is basically
memcmp while comparison may use collation.
Embarrassingly, I was unaware of this patch and started prototyping
> exactly the same thing independently[1]. I hadn't got very far and
> will now abandon that, but that's one thing I did differently. Two
> other things that may be different: I had a special case for groups of
> size 1 that skipped the sorting, and I only sorted on the suffix
> because I didn't put tuples with different prefixes into the sorter (I
> was assuming that tuplesort_reset was going to be super efficient,
> though I hadn't got around to writing that). I gather that you have
> determined empirically that it's better to be able to sort groups of
> at least MIN_GROUP_SIZE than to be able to skip the comparisons on the
> leading attributes, but why is that the case?
>
Right. The issue that not only case of one tuple per group could cause
overhead, but few tuples (like 2 or 3) is also case of overhead. Also,
overhead is related not only to sorting. While investigate of regression
case provided by Heikki [1], I've seen extra time spent mostly in extra
copying of sample tuple and comparison with that. In order to cope this
overhead I've introduced MIN_GROUP_SIZE which allows to skip copying sample
tuples too frequently.
[1]
https://www.postgresql.org/message-id/2c59b009-61d3-9350-04ee-4b701eb93101@iki.fi
------
Alexander Korotkov
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company
Commits
-
Further adjustments to Hashagg EXPLAIN ANALYZE output
- 40efbf8706cd 14.0 cited
-
Rework EXPLAIN format for incremental sort
- 6a918c3ac8a6 13.0 landed
-
Fix typos and improve incremental sort comments
- 1a40d37a9faf 13.0 landed
-
Stabilize incremental_sort tests
- cea09246e578 13.0 landed
-
Minor improvements in Incremental Sort explain
- d22782a5392f 13.0 landed
-
Consider Incremental Sort paths at additional places
- ba3e76cc571e 13.0 landed
-
Fix representation of SORT_TYPE_STILL_IN_PROGRESS.
- c7654f6a3779 13.0 landed
-
Fix failures in incremental_sort due to number of workers
- 23ba3b5ee278 13.0 landed
-
Fix show_incremental_sort_info with force_parallel_mode
- 7d6d82a52493 13.0 landed
-
Implement Incremental Sort
- d2d8a229bc58 13.0 landed
-
Fix handling of "Subplans Removed" field in EXPLAIN output.
- 7d91b604d9b5 13.0 cited
-
Fix EXPLAIN (SETTINGS) to follow policy about when to print empty fields.
- 3ec20c7091e9 13.0 cited
-
Ensure plpgsql result tuples have the right composite type marking.
- 5683b34956b4 13.0 cited
-
Propagate sort instrumentation from workers back to leader.
- bf11e7ee2e36 11.0 cited
-
Make new regression test case parallel-safe, and improve its output.
- 1177ab1dabf7 11.0 cited
-
Push limit through subqueries to underlying sort, where possible.
- 1f6d515a67ec 11.0 cited
-
Fix inappropriate printing of never-measured times in EXPLAIN.
- 4b234fd8bf21 9.6.0 cited
-
Fix some infelicities in EXPLAIN output for parallel query plans.
- 8ebb69f85445 9.6.0 cited