liaoxin01 opened a new pull request, #66545:
URL: https://github.com/apache/doris/pull/66545
### What problem does this PR solve?
Problem Summary:
`MemTable::_sort()` ran its own multi-key sort: `pdqsort` over a
`vector<shared_ptr<RowInBlock>>`, with the comparator passed as a
`std::function`
that called the virtual `IColumn::compare_at` once per comparison. Every
comparison therefore paid an indirect call, a virtual dispatch and two
pointer
chases into the block before it could even look at the key.
The query engine already has the sort this needs. `ColumnSorter`
(`be/src/exec/sort/sort_block.h`) implements the same sort-and-tie algorithm
--
sort by a key column, mark equal ranges, refine within them using the next
key
column -- but keeps an inline copy of the key next to the row id, so a
comparison
becomes a typed, inlinable operation on a compact array instead of a chain of
random accesses.
This PR makes `_sort()` and `_sort_by_cluster_keys()` build an
`IColumn::Permutation` and run it through `ColumnSorter`.
`_sort_one_column()`
and `class Tie` have no users left and are removed.
Measured with a micro-benchmark on 7.05M rows, one key column, Release build:
| key type | current | ColumnSorter | speedup |
| --- | --- | --- | --- |
| int32 | 13.2 s | 0.96 s | 13.7x |
| int64 | 13.3 s | 1.07 s | 12.4x |
| decimal128(20,2) | 13.7 s | 1.28 s | 10.7x |
| varchar ~4B | 19.6 s | 3.03 s | 6.5x |
| varchar ~40B | 21.9 s | 3.75 s | 5.8x |
| nullable int32 | 16.0 s | 1.04 s | 15.5x |
| nullable varchar ~4B | 25.4 s | 2.81 s | 9.0x |
Fixed-width keys gain the most because their inline value is the value
itself;
string keys still dereference the arena for the `memcmp`, so the longer the
key
the smaller the gain. No key type regressed.
The motivating case was a load whose profile showed `MemTableSortTime` at 83
s
across 7 memtables of a single tablet, with the sink blocked in
`WaitFlushLimitTime` for 45 s behind it.
### Behaviour change
Rows whose whole key is equal are now stabilised on **ascending** row
position
for every keys type. `DUP_KEYS` previously ordered them descending.
That descending order reproduced the iteration order of the skip list
MemTable
used before #18686: `SkipList::Insert` linked a new node *ahead* of the
existing
equal keys (`FindGreaterOrEqual` returns the first node >= key, and the new
node
is linked after `prev`), so iterating yielded equal keys in reverse insertion
order. The skip list is long gone; #18686, #19099 and #20392 each carried the
ternary along without it corresponding to any semantics.
Contents are unaffected -- DUP tables deduplicate nothing -- but rows
sharing the
key columns now keep insertion order inside a segment instead of being
reversed,
so a query without `ORDER BY` may return them in a different order.
If reviewers prefer to keep the old order, the direction is a one-line
change in
`_sort_permutation_by_key_columns()`; I removed it because nothing appears to
depend on it and it was the only reason `_sort()` needed to know its keys
type.
### Release note
None
### Check List (For Author)
- Test
- [x] Unit Test
- [ ] Regression test
- [ ] Manual test (add detailed scripts or steps below)
- [ ] No need to test or manual test. Explain why:
- [ ] This is a refactor/code format and no logic has been changed.
- [ ] Previous test can cover this change.
- [ ] No code files have been changed.
- [ ] Other reason
`be/test/load/memtable/memtable_sort_test.cpp` previously only covered
`class Tie`. It now drives a `MemTable` through `insert()`/`to_block()` and
covers multi-column key ordering, nullable key ordering (NULL first),
insertion
order on equal keys, independence from how rows are split across `insert()`
calls, `UNIQUE_KEYS` last-writer-wins and `AGG_KEYS` aggregation.
The two ordering tests were verified to fail when the tie-break direction is
flipped back to descending, so they do discriminate rather than just pass.
Regression tests have **not** been run for the ordering change above; that
needs
a cluster and is the part reviewers should weigh most.
- Behavior changed:
- [ ] No.
- [x] Yes. Equal keys in a DUP table keep insertion order instead of
being
reversed; see the section above.
- Does this need documentation?
- [x] No.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]