Skip to content

[DNM] executor: optimize range scan for cached table#67430

Closed
you06 wants to merge 48 commits into
masterfrom
perf/cached-table
Closed

[DNM] executor: optimize range scan for cached table#67430
you06 wants to merge 48 commits into
masterfrom
perf/cached-table

Conversation

@you06
Copy link
Copy Markdown
Contributor

@you06 you06 commented Mar 30, 2026

Summary

  • Cherry-pick of PR [DNM] executor: optimize range scan for cached table #66640 onto PR Codex/plan cache hint only #67412 base
  • Optimizes cached table scan performance with:
    • Expression evaluation hot path optimizations (cache GetType, skip redundant allocations)
    • Dedicated fast path for cached table scan in UnionScanExec
    • Decode path optimizations across rowcodec/tablecodec/chunk/codec/types
    • Query-level result set cache for cached tables
    • Pre-decoded datum cache to skip per-query KV decode overhead

Test plan

  • make server builds successfully
  • CI passes

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added result set caching for queries on cached tables with new hit/miss metrics and memory tracking
    • Introduced tidb_plan_cache_policy session variable to control plan caching behavior with "hint_only" mode
    • Added Result_cache_hit field to slow query logs
  • Improvements

    • Enhanced row and index decoding performance with cached datum access and allocation reuse
    • Improved timezone handling for cached TIMESTAMP columns
  • Metrics

    • New Prometheus counters for result cache hits, misses, and evictions
    • New gauge for result cache memory usage

qw4990 and others added 30 commits March 30, 2026 15:47
Cache c.GetType(ctx) into a local variable in Constant.EvalInt and
Constant.EvalReal to avoid redundant method calls. Also remove the
sleep 1200 between work file iterations in the cached table scan
run script.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
For Constant expressions without ParamMarker, directly access RetType
to get the flag instead of calling GetType(sctx), reducing overhead in
integer comparison operations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…located FieldType

Add getTypeNonAlloc that fills a caller-provided FieldType buffer on the
stack for ParamMarker constants instead of allocating via NewFieldType.
Replace all GetType calls in Eval{Int,Real,String,Decimal,Time,Duration,
JSON,VectorFloat32} with this non-allocating variant to reduce GC pressure
in hot paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
For cached tables, getSnapshotRow() always returns nil, making the
merge logic in getOneRow() unnecessary overhead. Add a dedicated
nextForCacheTable() method that reads directly from addedRowsIter,
skipping the snapshot row merge and reducing per-row cost.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce memRowsBatchIterForTable for cached table scans.
It decodes rows into chunks and applies vectorized filters when enabled.
Add a benchmark comparing row vs batch iter.
Add a specialized decoder for fixed-length int-handle row keys to reduce overhead in mem table scans, and add tests/bench updates.
- Add wide-row decode and mixed-append benchmarks\n- Optimize chunk fixed-len appends and fixed AppendNull\n- Cache per-column decode metadata in ChunkDecoder\n- Add correctness tests and cached-table-scan work plans
Pass buf and preAlloc parameters through to decodeIndexKvGeneral and
decodeIndexKvForClusteredIndexVersion1 so callers (DecodeIndexKVEx) can
reuse pre-allocated slices. Replace CutIndexKeyNew with CutIndexKeyTo
to write into the pre-allocated result slice directly and use
reEncodeHandleTo instead of reEncodeHandle to append in-place. Remove
the now-unused reEncodeHandle helper.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ue decoding

Add IndexRestoredDecoder to cache the colIDs map and BytesDecoder across
rows, avoiding per-row allocations in decodeRestoredValues. Introduce
arena-based encodeOldDatumToArena and DecodeToBytesNoHandleInto to
further reduce allocations during index KV decoding in the general path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Time.AppendString() that formats date/datetime/timestamp via direct
byte writes instead of fmt.Sprintf and string concatenation, eliminating
allocations. Rewrite Time.String() to delegate to AppendString. In
DumpTextRow, use AppendString with the existing tmp buffer to avoid
hack.Slice(t.String()) allocations. Also bump tmp buffer from 20 to 32
bytes to accommodate the longest datetime+fsp string.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cache HandleStatus, time.Location, and EvalContext in memIndexReader
so they are computed once per scan instead of on every row decode.
Also use DecodeColumnValueWithDatum to avoid intermediate allocations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce a per-cached-table result set cache that stores query result
sets keyed by plan digest and parameter hash. The cache is invalidated
when the table lease expires, avoiding stale reads without eviction
logic. Includes unit tests for hit/miss, capacity limits, and
concurrency safety.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ensure the cached table result set cache is properly invalidated when
data may become stale: on data reload, lease renewal failure, and
before acquiring a write lock.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add CanCacheResultSet to determine whether a query's result set can be
served from the cached table result set cache. The check rejects queries
with non-deterministic functions (NOW, RAND, UUID, etc.), user/session
variable references, FOR UPDATE locks, DML context, and non-cached
tables. Includes comprehensive unit tests covering all rejection paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add BuildResultCacheKey to construct cache keys from plan digest and
parameter hashes, enabling per-query result set caching for cached tables.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d tables

Wire up the result set cache by wrapping top-level executors with
CachedResultExec. Move ResultCacheKey to the table package so it can be
referenced across executor and planner without import cycles, and expose
GetCachedResult/PutCachedResult on the CachedTable interface.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add metrics (hit/miss counters, memory gauge, eviction counter), slow
log field (Result_cache_hit), EXPLAIN ANALYZE runtime stats, and the
StmtCtx.ReadFromResultCache flag to provide visibility into result set
cache behavior on cached tables.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…e fixes

Add secondary paramBytes verification on cache lookups to guard against
FNV-1a hash collisions. Fall back to OriginalSQL hashing when plan cache
parameterization is bypassed (e.g. non-prepared plan cache disabled).
Exclude PointGetPlan and BatchPointGetPlan from result set caching since
they bypass plan cache parameterization. Remove obsolete workplan files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
you06 and others added 11 commits March 31, 2026 01:04
Add memCachedDatumIter that reads pre-decoded chunks from CachedDatumData,
skipping KV decode entirely. Wire it into memTableReader.getMemRowsIter
and UnionScanExec.handleCachedTable for cached table scans.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Store TIMESTAMP columns in UTC in datum cache with tracked indices for
per-session timezone conversion. Add timezone-aware test for cached table
result set cache.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cover projection, desc scan, filters, timezone conversion, multi-chunk
desc, and benchmark for the cached datum fast-path iterator.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cherry-pick of 1ee4b3c from PR #66640 (Part 5).

Adds CachedIndexDatumData and BuildCachedIndexDatumData for pre-decoding
index KV entries into datum maps at cache load time. The executor builder
now looks up index datum caches via GetCachedIndexDatumData interface and
populates indexDatumCaches on UnionScanExec.
… condition checks

Cherry-pick of def0558 from PR #66640 (Part 5).

- Reuse us.mutableRow field instead of allocating a new MutRow per Next()
  call in both Next and nextForCacheTable.
- Add direct-to-chunk datum write fast path in nextForCacheTable when no
  virtual columns or conditions exist.
- Skip EvalBool when conditions slice is empty in memIndexReader.getMemRows
  and memRowsIterForIndex.Next.
- Reuse mutableRow in memCachedDatumIter instead of allocating via
  MutRowFromDatums on every iteration.

Note: removeRedundantAccessConditions was already cherry-picked in Part 4.
Cherry-pick of e21ed51 from PR #66640 (Part 5).

Guard against nil timezone in EncodeMySQLTime and keep index decode
buffer preallocation to avoid unnecessary allocations.
Cherry-pick of d143283 from PR #66640 (Part 5).

Fix cached datum decode handling and improve result cache memory
accounting consistency. Update test assertions accordingly.
Cherry-pick of 1cde4d3 from PR #66640 (Part 5).

Add GetCachedDatumDataForMemBuffer and GetCachedIndexDatumDataForMemBuffer
methods that validate the MemBuffer matches the current cacheData generation,
preventing stale datum cache usage across lease boundaries.
Cherry-pick of 979f905 from PR #66640 (Part 5).

Use origin default values when building datum cache for columns that
are missing from the encoded row data, ensuring newly added columns
with defaults are properly filled.
Cherry-pick of 10fc5ba from PR #66640 (Part 5).

Prefer GetCachedDatumDataForMemBuffer and GetCachedIndexDatumDataForMemBuffer
over unpinned accessors when looking up datum caches in handleCachedTable,
ensuring the datum cache matches the same cacheData generation as the
MemBuffer being read.
Cherry-pick of 57df0aa from PR #66640 (Part 5).

- Add kvRangesCoverFullTable guard to only use datum cache fast path
  when the scan covers the full table record range and txn membuffer
  has no overriding entries.
- Add safety checks in CachedResultExec for schema match validation.
- Add comprehensive tests for datum cache fallback and backfill edge cases.
@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented Mar 30, 2026

Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@ti-chi-bot ti-chi-bot Bot added the do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. label Mar 30, 2026
@pantheon-ai
Copy link
Copy Markdown

pantheon-ai Bot commented Mar 30, 2026

Review failed due to infrastructure/execution failure after retries. Please re-trigger review.

ℹ️ Learn more details on Pantheon AI.

@ti-chi-bot ti-chi-bot Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Mar 30, 2026
@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented Mar 30, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign benjamin2037, terry1purcell, xuhuaiyu for approval. For more information see the Code Review Process.
Please ensure that each of them provides their approval before proceeding.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@tiprow
Copy link
Copy Markdown

tiprow Bot commented Mar 30, 2026

Hi @you06. Thanks for your PR.

PRs from untrusted users cannot be marked as trusted with /ok-to-test in this repo meaning untrusted PR authors can never trigger tests themselves. Collaborators can still trigger tests on the PR using /test all.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@ti-chi-bot ti-chi-bot Bot added the sig/planner SIG: Planner label Mar 30, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 30, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 9e407c81-3c7d-4589-b86b-8ebac6ee97e2

📥 Commits

Reviewing files that changed from the base of the PR and between d5347e2 and 9d3cd9e.

📒 Files selected for processing (67)
  • pkg/executor/BUILD.bazel
  • pkg/executor/adapter.go
  • pkg/executor/adapter_slow_log.go
  • pkg/executor/builder.go
  • pkg/executor/cached_result_exec.go
  • pkg/executor/cached_result_exec_test.go
  • pkg/executor/mem_reader.go
  • pkg/executor/mem_reader_test.go
  • pkg/executor/prepared.go
  • pkg/executor/slow_query.go
  • pkg/executor/union_scan.go
  • pkg/expression/builtin_compare.go
  • pkg/expression/constant.go
  • pkg/expression/util.go
  • pkg/infoschema/tables.go
  • pkg/metrics/executor.go
  • pkg/metrics/metrics.go
  • pkg/parser/ast/misc.go
  • pkg/planner/core/BUILD.bazel
  • pkg/planner/core/casetest/plancache/BUILD.bazel
  • pkg/planner/core/casetest/plancache/plan_cache_suite_test.go
  • pkg/planner/core/plan_cache.go
  • pkg/planner/core/plan_cache_utils.go
  • pkg/planner/core/result_cache_check.go
  • pkg/planner/core/result_cache_check_test.go
  • pkg/planner/core/result_cache_key.go
  • pkg/planner/core/result_cache_key_test.go
  • pkg/server/internal/column/column.go
  • pkg/sessionctx/stmtctx/stmtctx.go
  • pkg/sessionctx/vardef/tidb_vars.go
  • pkg/sessionctx/variable/session.go
  • pkg/sessionctx/variable/setvar_affect.go
  • pkg/sessionctx/variable/slow_log.go
  • pkg/sessionctx/variable/sysvar.go
  • pkg/table/table.go
  • pkg/table/tables/BUILD.bazel
  • pkg/table/tables/cache.go
  • pkg/table/tables/cache_test.go
  • pkg/table/tables/cache_tz_test.go
  • pkg/table/tables/cached_datum.go
  • pkg/table/tables/cached_datum_test.go
  • pkg/table/tables/result_cache.go
  • pkg/table/tables/result_cache_test.go
  • pkg/tablecodec/BUILD.bazel
  • pkg/tablecodec/bench_test.go
  • pkg/tablecodec/tablecodec.go
  • pkg/tablecodec/tablecodec_test.go
  • pkg/types/field_type.go
  • pkg/types/time.go
  • pkg/types/time_test.go
  • pkg/util/chunk/chunk_test.go
  • pkg/util/chunk/column.go
  • pkg/util/chunk/pool.go
  • pkg/util/chunk/pool_test.go
  • pkg/util/codec/codec.go
  • pkg/util/codec/codec_test.go
  • pkg/util/execdetails/execdetails.go
  • pkg/util/execdetails/execdetails_test.go
  • pkg/util/execdetails/runtime_stats.go
  • pkg/util/hint/hint.go
  • pkg/util/rowcodec/BUILD.bazel
  • pkg/util/rowcodec/bench_test.go
  • pkg/util/rowcodec/common.go
  • pkg/util/rowcodec/decoder.go
  • pkg/util/rowcodec/decoder_test.go
  • pkg/util/rowcodec/encoder.go
  • pkg/util/rowcodec/row.go

📝 Walkthrough

Walkthrough

Adds a result-set caching subsystem: planner eligibility and key builders, a CachedResultExec executor wrapper, table-level result and pre-decoded datum/index caches, executor integration (builder/union-scan/mem-reader), metrics/slow-log/runtime-stats, many decoder/rowcodec optimizations, and extensive tests/benchmarks.

Changes

Cohort / File(s) Summary
Executor: wrapper & tests
pkg/executor/cached_result_exec.go, pkg/executor/cached_result_exec_test.go
New CachedResultExec that serves cached chunks on hit or collects rows and backfills on close; tests validate lifecycle, backfill suppression on Close error, and StmtCtx flag handling.
Executor integration & builder
pkg/executor/adapter.go, pkg/executor/prepared.go, pkg/executor/builder.go, pkg/executor/adapter_slow_log.go, pkg/executor/slow_query.go
Builder tracks cached-table state, can wrap top-level executors via wrapWithResultCache, applies wrapper in exec build paths, and surfaces result-cache hit into slow-log/StmtCtx.
Mem-reader, union-scan & iterators
pkg/executor/mem_reader.go, pkg/executor/mem_reader_test.go, pkg/executor/union_scan.go
Adds pre-decoded datum/index cache paths, batch iterator for full-table scans, handle-decoding helpers, timezone-aware timestamp projection, and avoids predicate evaluation when unnecessary; includes many unit/bench tests.
Planner: eligibility & key construction
pkg/planner/core/result_cache_check.go, pkg/planner/core/result_cache_check_test.go, pkg/planner/core/result_cache_key.go, pkg/planner/core/result_cache_key_test.go
New CanCacheResultSet rules and BuildResultCacheKey producing plan-digest + param hash + verification payload; tests validate sensitivity to params, timezone, collation, bindings, and mutability.
Table caches & result-set store
pkg/table/tables/cache.go, pkg/table/tables/cached_datum.go, pkg/table/tables/result_cache.go, pkg/table/tables/*_test.go, pkg/table/table.go
Adds in-memory result-set cache and pre-decoded datum/index caches pinned to MemBuffer generations, memory accounting/invalidation, Get/Put semantics, and many tests (including TZ handling).
Metrics, slow-log, execdetails, infoschema, stmtctx
pkg/metrics/executor.go, pkg/metrics/metrics.go, pkg/sessionctx/stmtctx/stmtctx.go, pkg/sessionctx/variable/slow_log.go, pkg/util/execdetails/*, pkg/infoschema/tables.go
New Prometheus metrics (hit/miss/memory/evict), StmtCtx.ReadFromResultCache flag, ResultCacheRuntimeStats runtime stat, slow-log field/column, and infoschema column added.
Plan-cache policy & hints
pkg/planner/core/plan_cache.go, pkg/planner/core/plan_cache_utils.go, pkg/util/hint/hint.go, pkg/sessionctx/vardef/tidb_vars.go, pkg/sessionctx/variable/*
Adds tidb_plan_cache_policy (all/hint_only) and USE_PLAN_CACHE() hint; plan-cache enabling respects policy and matched bindings.
Rowcodec / tablecodec improvements & tests
pkg/tablecodec/tablecodec.go, pkg/util/rowcodec/decoder.go, pkg/util/rowcodec/*, pkg/tablecodec/*
Introduces IndexRestoredDecoder, decode allocation reductions, compiled-column decoding, arena helpers, and matching tests/benchmarks.
Chunk/pool/types/codec/time/utils & tests
pkg/util/chunk/*, pkg/util/codec/*, pkg/types/*, pkg/expression/*, pkg/server/internal/column/column.go
Chunk append refactor to reduce allocations, pool de-duplication, Time.AppendString fast path, codec/time guards, constant-type helpers, and related tests/benchmarks.
Build/test config & parser hint restore
pkg/*/BUILD.bazel, pkg/planner/core/casetest/plancache/plan_cache_suite_test.go, pkg/parser/ast/misc.go
Added sources/tests to Bazel targets, adjusted test shard counts, and treat use_plan_cache as a no-argument hint during Restore.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant ExecAdapter as Exec Adapter
    participant Builder as Executor Builder
    participant CRE as CachedResultExec
    participant Cache as CachedTable
    participant Src as Wrapped Executor

    Client->>ExecAdapter: Execute(query)
    ExecAdapter->>Builder: build(plan)
    Builder->>Builder: CanCacheResultSet(...) & BuildResultCacheKey(...)
    Builder->>CRE: wrapWithResultCache(exec, stmtNode, plan)
    CRE->>Cache: GetCachedResult(key, paramBytes)
    alt hit
        Cache-->>CRE: chunks + fieldTypes, ok=true
        CRE->>CRE: schemaMatch -> set hit state, StmtCtx.ReadFromResultCache=true
        CRE-->>Client: Next() returns cached rows
    else miss
        Cache-->>CRE: miss
        CRE->>Src: Open() (delegate to wrapped exec)
        Src-->>CRE: Next() returns rows
        CRE->>CRE: collect chunks while Next()
        Client->>CRE: Close()
        CRE->>Cache: PutCachedResult(key, paramBytes, collectedChunks, schema)
    end
Loading
sequenceDiagram
    participant Planner
    participant KeyBuilder
    participant Session
    participant StmtCtx

    Planner->>Planner: CanCacheResultSet(stmt, plan, inDML)
    alt cacheable
        Planner->>KeyBuilder: BuildResultCacheKey(sctx)
        KeyBuilder->>StmtCtx: get plan digest
        KeyBuilder->>Session: get timezone, charset, collation
        KeyBuilder->>KeyBuilder: encode params, build verification payload, compute ParamHash
        KeyBuilder-->>Planner: ResultCacheKey + paramBytes
    else not cacheable
        Planner-->>Planner: skip result cache
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

ok-to-test, skip-issue-check

Suggested reviewers

  • wjhuang2016
  • AilinKid
  • OliverS929
  • mjonss

Poem

🐰
I hopped through plans and cached bouquets,
Stored rows snug for brighter days,
No needless scans to make me hop,
Metrics cheer and slow-logs stop,
A crunchy query-carrot — hop, hooray!

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/cached-table

Warning

Tools execution failed with the following error:

Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@you06 you06 force-pushed the perf/cached-table branch from 70e9ff3 to a930d09 Compare March 30, 2026 16:14
@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented Mar 30, 2026

@you06: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
pull-build-next-gen a930d09 link true /test pull-build-next-gen
idc-jenkins-ci-tidb/build a930d09 link true /test build

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented Mar 30, 2026

[FORMAT CHECKER NOTIFICATION]

Notice: To remove the do-not-merge/needs-linked-issue label, please provide the linked issue number on one line in the PR body, for example: Issue Number: close #123 or Issue Number: ref #456.

📖 For more info, you can check the "Contribute Code" section in the development guide.


Notice: To remove the do-not-merge/needs-tests-checked label, please finished the tests then check the finished items in description.

For example:

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No code

📖 For more info, you can check the "Contribute Code" section in the development guide.

@you06
Copy link
Copy Markdown
Contributor Author

you06 commented Mar 30, 2026

Dev branch in the wrong repo...

@you06 you06 closed this Mar 30, 2026
@you06 you06 deleted the perf/cached-table branch March 30, 2026 16:21
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 30, 2026

Caution

Review failed

An error occurred during the review process. Please try again later.

📝 Walkthrough

Walkthrough

Adds result-set caching for cached-table queries: planner eligibility/key builders, a new CachedResultExec executor, in-memory result cache and pre-decoded datum/index caches, executor/builder integration and metrics/slow-log/runtime-stats, plus many supporting decoding, iterator, and test changes.

Changes

Cohort / File(s) Summary
Executor: result cache wrapper & tests
pkg/executor/cached_result_exec.go, pkg/executor/cached_result_exec_test.go
New CachedResultExec that loads/stores cached chunks, validates schema, records metrics and StmtCtx flag; tests for close/backfill behavior.
Executor integration & builder changes
pkg/executor/adapter.go, pkg/executor/prepared.go, pkg/executor/builder.go, pkg/executor/adapter_slow_log.go, pkg/executor/slow_query.go
Builder tracks cached-table state, adds wrapWithResultCache, applies wrapper in ExecStmt and ExecuteExec build paths, and surfaces result-cache hit flag to slow-log.
Mem-reader & union-scan paths
pkg/executor/mem_reader.go, pkg/executor/mem_reader_test.go, pkg/executor/union_scan.go
Add pre-decoded datum/index caches support, fast cached-table iteration/batch iterators, optimized handle decoding and predicate evaluation; tests/benchmarks added.
Planner: eligibility and key construction
pkg/planner/core/result_cache_check.go, pkg/planner/core/result_cache_check_test.go, pkg/planner/core/result_cache_key.go, pkg/planner/core/result_cache_key_test.go
New CanCacheResultSet checks and BuildResultCacheKey to derive ResultCacheKey + verification payload including params/timezone/collation; extensive tests.
Table-level caches & result-set store
pkg/table/tables/cache.go, pkg/table/tables/cached_datum.go, pkg/table/tables/result_cache.go, pkg/table/tables/*.go tests, pkg/table/table.go
cachedTable: pre-decoded datum/index caches, result cache membrane with memory accounting/invalidation, accessors and interface extensions; increased cached table size limit; tests and TZ-aware behavior.
Metrics, slow-log, execdetails, infoschema
pkg/metrics/executor.go, pkg/metrics/metrics.go, pkg/sessionctx/stmtctx/stmtctx.go, pkg/sessionctx/variable/slow_log.go, pkg/util/execdetails/*, pkg/infoschema/tables.go
New Prometheus metrics (hit/miss/memory/evict), StmtCtx.ReadFromResultCache flag, ResultCacheRuntimeStats, slow-log column/field and infoschema column entry.
Plan-cache policy & hints
pkg/planner/core/plan_cache.go, pkg/planner/core/plan_cache_utils.go, pkg/util/hint/hint.go, pkg/sessionctx/vardef/tidb_vars.go, pkg/sessionctx/variable/*
Adds tidb_plan_cache_policy (all/hint_only) and USE_PLAN_CACHE() hint; plan-cache enabling now considers policy and bindings.
Decoding & rowcodec improvements
pkg/tablecodec/tablecodec.go, pkg/util/rowcodec/decoder.go, pkg/util/rowcodec/*, pkg/tablecodec/*
Add IndexRestoredDecoder and decode-path refactors to reduce allocations, decoder compiled-col caching, arena-based byte helpers and related tests/benchmarks.
Chunk, pool, types, codec, misc utilities & tests
pkg/util/chunk/*, pkg/util/codec/*, pkg/types/*, pkg/expression/*, pkg/server/internal/column/column.go
Performance and allocation reductions: chunk append refactor, pool duplicate-column handling, Time.AppendString, constant.getTypeNonAlloc, nil-loc guards, and multiple tests/benchmarks.
Build/test config updates
pkg/*/BUILD.bazel, pkg/planner/core/casetest/plancache/plan_cache_suite_test.go, pkg/parser/ast/misc.go
Added new source/test files to Bazel targets, adjusted test shard counts, and restored use_plan_cache hint formatting.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Executor as Exec Adapter
    participant Builder as Executor Builder
    participant CRE as CachedResultExec
    participant Cache as CachedTable
    participant Reader as MemReader

    Client->>Executor: Execute(query)
    Executor->>Builder: build(plan)
    Builder->>Builder: CanCacheResultSet(...) & BuildResultCacheKey(...)
    Builder->>CRE: wrapWithResultCache(exec, stmtNode, plan)

    CRE->>Cache: GetCachedResult(key, params)
    alt hit
        Cache-->>CRE: chunks + fieldTypes, ok=true
        CRE->>CRE: schemaMatch -> set hit state, StmtCtx.ReadFromResultCache=true, increment hit metric
    else miss
        Cache-->>CRE: miss
        CRE->>Reader: Open() (delegate)
        Reader->>Reader: use pre-decoded datum/index caches or KV scan
        CRE->>CRE: collect chunks while Next()
        Client->>CRE: Close()
        CRE->>Cache: PutCachedResult(key, params, collectedChunks, schema)
        CRE->>CRE: increment miss metric
    end

    Client->>CRE: Next() -> returns rows (either copied from cache or delegated)
Loading
sequenceDiagram
    participant Planner
    participant KeyBuilder
    participant Session
    participant StmtCtx

    Planner->>Planner: CanCacheResultSet(stmt, plan, inDML)
    alt cacheable
        Planner->>KeyBuilder: BuildResultCacheKey(sctx)
        KeyBuilder->>StmtCtx: get plan digest
        KeyBuilder->>Session: get timezone, charset, collation
        KeyBuilder->>KeyBuilder: encode params, hash (ParamHash)
        KeyBuilder-->>Planner: ResultCacheKey + paramBytes
    else not cacheable
        Planner-->>Planner: skip result cache
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

ok-to-test, release-note-none

Suggested reviewers

  • wjhuang2016
  • XuHuaiyu

Poem

🐰
I hopped along the planner's trail,
Cached rows snug in memory's dale,
No extra scans to wear my paws,
Metrics gleam and slow-log claws,
A carrot-fast query—what a tale!

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/cached-table

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge/needs-linked-issue do-not-merge/needs-tests-checked do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. sig/planner SIG: Planner size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants