From 922510f4d7570b42838e015787ed53abfa8761a1 Mon Sep 17 00:00:00 2001 From: ben zhang Date: Thu, 15 Oct 2026 16:52:54 +0000 Subject: [PATCH] Use the turn index for turn-scoped item pagination (#54351) ## Why A thread-wide index can scan earlier turns when a turn's final item page is underfilled. ## What changed Force `idx_thread_items_by_turn_page` for turn-scoped item queries when neither `item_ids` nor `after_updated_at_ordinal` is set. GitOrigin-RevId: 63c86fafa08446351a5d9828b479c497c76a8555 --- .../src/local/thread_history/segment_paging.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/codex-rs/thread-store/src/local/thread_history/segment_paging.rs b/codex-rs/thread-store/src/local/thread_history/segment_paging.rs index 7c647c4dcb..24a23e64c4 100644 --- a/codex-rs/thread-store/src/local/thread_history/segment_paging.rs +++ b/codex-rs/thread-store/src/local/thread_history/segment_paging.rs @@ -292,11 +292,18 @@ pub(super) async fn page_item_rows( let mut query = QueryBuilder::::new( r#" SELECT turn_id, item_id, rollout_ordinal, updated_at_ordinal, created_at_ms, started_at_ms, completed_at_ms, item_json -FROM thread_items -WHERE thread_id = - "#, +FROM thread_items"#, ); - query.push_bind(segment.rollout_id().to_string()); + if params.turn_id.is_some() + && params.item_ids.is_none() + && params.after_updated_at_ordinal.is_none() + { + // A thread-wide index can scan earlier turns when a turn's final page is underfilled. + query.push(" INDEXED BY idx_thread_items_by_turn_page"); + } + query + .push(" WHERE thread_id = ") + .push_bind(segment.rollout_id().to_string()); push_segment_range(&mut query, segment)?; if let Some(after_updated_at_ordinal) = params.after_updated_at_ordinal { query