Skip to content

Commit 5d70423

Browse files
committedMar 12, 2025
Enumerate aggregates in aggregate_id order
Ordering by `[events_partition_key, aggregate_id]` is very inefficient since the `aggregates` table is partitioned by `aggregate_id`. Ordering by `aggregate_id` should allow fast index scans. Retrieving the associated event streams will be slower though, since they are no longer co-located by using the `events_partition_key`.
1 parent 319025b commit 5d70423

File tree

2 files changed

+17
-11
lines changed

2 files changed

+17
-11
lines changed
 

‎lib/sequent/core/event_store.rb

+4-8
Original file line numberDiff line numberDiff line change
@@ -224,28 +224,24 @@ def load_events_since_marked_position(mark)
224224
# aggregate root type can be specified (as a string) to only yield aggregate ids of the indicated type.
225225
def event_streams_enumerator(aggregate_type: nil, group_size: 100)
226226
Enumerator.new do |yielder|
227-
last_events_partition_key = ''
228227
last_aggregate_id = nil
229228
loop do
230229
aggregate_rows = ActiveRecord::Base.connection.exec_query(
231-
'SELECT events_partition_key, aggregate_id
232-
FROM aggregates
230+
'SELECT aggregate_id
231+
FROM aggregates
233232
WHERE ($1::text IS NULL OR aggregate_type_id = (SELECT id FROM aggregate_types WHERE type = $1))
234-
AND ((events_partition_key >= $3 AND $4::uuid IS NULL)
235-
OR (events_partition_key, aggregate_id) > ($3, $4))
236-
ORDER BY 1, 2
233+
AND ($3::uuid IS NULL OR aggregate_id > $3)
234+
ORDER BY 1
237235
LIMIT $2',
238236
'aggregates_to_update',
239237
[
240238
aggregate_type,
241239
group_size,
242-
last_events_partition_key,
243240
last_aggregate_id,
244241
],
245242
).to_a
246243
break if aggregate_rows.empty?
247244

248-
last_events_partition_key = aggregate_rows.last['events_partition_key']
249245
last_aggregate_id = aggregate_rows.last['aggregate_id']
250246

251247
yielder << aggregate_rows.map { |x| x['aggregate_id'] }

‎spec/lib/sequent/core/event_store_spec.rb

+13-3
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,8 @@ class MyAggregate < Sequent::Core::AggregateRoot
407407
end
408408
let(:ordered_aggregate_ids) do
409409
event_streams
410-
.sort_by { |s| [s.events_partition_key, s.aggregate_id] }
411410
.map(&:aggregate_id)
411+
.sort
412412
end
413413

414414
let(:group_size) { 100 }
@@ -435,7 +435,12 @@ class MyAggregate < Sequent::Core::AggregateRoot
435435
it 'finds all event streams of a specific type' do
436436
subject = event_store.event_streams_enumerator(aggregate_type: 'MyAggregate0', group_size:)
437437
aggregate_ids = subject.next
438-
expect(aggregate_ids).to eq(ordered_aggregate_ids[0...10])
438+
expect(aggregate_ids).to eq(
439+
event_streams
440+
.select { |s| s.aggregate_type == 'MyAggregate0' }
441+
.map(&:aggregate_id)
442+
.sort,
443+
)
439444
expect { subject.next }.to raise_error(StopIteration)
440445
end
441446
end
@@ -455,7 +460,12 @@ class MyAggregate < Sequent::Core::AggregateRoot
455460
it 'finds all event streams of a specific type' do
456461
subject = event_store.event_streams_enumerator(aggregate_type: 'MyAggregate1', group_size:)
457462
aggregate_ids = subject.next
458-
expect(aggregate_ids).to eq(ordered_aggregate_ids[10..])
463+
expect(aggregate_ids).to eq(
464+
event_streams
465+
.select { |s| s.aggregate_type == 'MyAggregate1' }
466+
.map(&:aggregate_id)
467+
.sort,
468+
)
459469
expect { subject.next }.to raise_error(StopIteration)
460470
end
461471
end

0 commit comments

Comments
 (0)
Please sign in to comment.