Skip to content

perf(bigquery): [T1-15] eliminate eager blocking jobs.get RPCs on query pagination and fast-path queries - #20

Open
lqiu96 wants to merge 1 commit into
mainfrom
perf/bq-t1-15-lazy-jobs-get-pagination
Open

lqiu96 wants to merge 1 commit into
mainfrom
perf/bq-t1-15-lazy-jobs-get-pagination

Conversation

@lqiu96

@lqiu96 lqiu96 commented Oct 13, 2026

Copy link
Copy Markdown
Owner

Summary & Bottleneck

  • In BigQueryImpl.queryRpc, when Page 1 completes with a non-null pageToken, new QueryPageFetcher(...) executes a synchronous blocking this.job = getJob(jobId) HTTP RPC inside its constructor before returning Page 1 to the caller. If the caller only inspects Page 1, the jobs.get RPC is wasted, and even for multi-page consumers it adds a full HTTP round-trip to time-to-first-row. QueryPageFetcher also extends java.lang.Thread without ever starting the thread, registering an unstarted thread in the active ThreadGroup on every multi-page query.
  • In ConnectionImpl.processQueryResponseResults, getDestinationTable(jobId) executes a synchronous blocking jobs.get HTTP RPC even when results.getPageToken() == null (single-page fast-path queries) and submits an unnecessary background pagination task.
  • In ConnectionImpl.getSubsequentQueryResultsWithJob and tableDataList, Schema.fromPb(firstPage.getSchema()) is parsed twice and getQueryJobRpc(jobId) (jobs.get HTTP RPC) is invoked up to three times for the same JobId.

Changes

  • Remove extends Thread from QueryPageFetcher and defer getJob(jobId) and destinationTable lookup lazily into QueryPageFetcher.getNextPage() in java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java.
  • Guard getDestinationTable(jobId) and runNextPageTaskAsync behind pageToken != null in processQueryResponseResults and tableDataList in java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ConnectionImpl.java.
  • Deduplicate Schema.fromPb in getSubsequentQueryResultsWithJob and cache the last resolved Job per JobId in getQueryJobRpc in java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ConnectionImpl.java.
  • Add a unit test in java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/ConnectionImplTest.java verifying that single-page processQueryResponseResults skips getDestinationTable and getQueryJobSkipExceptionTranslation.

Expected Impact

  • Saves 1 full synchronous HTTP round-trip (~50 to 150 ms) on every single-page Connection fast-path query and before Page 1 return on every multi-page BigQuery.query(...) call.
  • Saves 1 to 2 redundant jobs.get HTTP round-trips and 1 duplicate Schema.fromPb deserialization on Connection fallback and Read API queries.
  • Eliminates unstarted java.lang.Thread allocations and ThreadGroup.addUnstarted() overhead in QueryPageFetcher.

Verification

  • Ran ConnectionImplTest and BigQueryImplTest via Maven (174 tests run, 0 failures).

@lqiu96
lqiu96 force-pushed the perf/bq-t1-15-lazy-jobs-get-pagination branch from 9c05bb2 to 4b1750c Compare October 13, 2026 20:48
@lqiu96
lqiu96 force-pushed the perf/bq-t1-15-lazy-jobs-get-pagination branch from 4b1750c to 302b1a9 Compare October 13, 2026 21:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant