This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-website.git
The following commit(s) were added to refs/heads/master by this push:
new cfd75757700 [doc](lance) update cache in lance (#4126)
cfd75757700 is described below
commit cfd757577004534f25ebc7b2069764bb4e948f26
Author: zhangstar333 <[email protected]>
AuthorDate: Thu Sep 17 21:05:18 2026 +0800
[doc](lance) update cache in lance (#4126)
## Versions
- [ ] dev
- [x] 4.x
- [ ] 3.x
- [ ] 2.1 or older (not covered by version/language sync gate)
## Languages
- [x] Chinese
- [x] English
## Docs Checklist
- [ ] Checked by AI
- [ ] Test Cases Built
- [ ] Updated required version and language counterparts, or explained
why not
- [ ] If only one language changed, confirmed whether source/translation
counterparts need sync
---
.../lakehouse/catalogs/lance-catalog.mdx | 80 +++++++++++++++++++--
.../lakehouse/catalogs/lance-catalog.mdx | 82 ++++++++++++++++++++--
2 files changed, 148 insertions(+), 14 deletions(-)
diff --git
a/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/lakehouse/catalogs/lance-catalog.mdx
b/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/lakehouse/catalogs/lance-catalog.mdx
index ced3c5faffa..da24382ebb9 100644
---
a/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/lakehouse/catalogs/lance-catalog.mdx
+++
b/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/lakehouse/catalogs/lance-catalog.mdx
@@ -42,13 +42,15 @@ Lance 是面向分析和 AI 场景的列式数据格式。Doris 可以通过 Lan
| 文件 TVF | 支持通过 `s3()` 和 `local()` 直接查询 Lance 数据集 |
| 向量检索 | 使用物理 Lance Index Segment 作为并行 Split,对未覆盖的 Fragment 保留 Flat Search
Split,并由 Doris 合并全局 Top-K |
| 全文检索 | 通过 `full_text_search()` 使用已有的 Lance FTS 倒排索引,支持 Match OR/AND 和 Phrase
查询,并由 Doris 合并全局 Top-K |
+| Lance Cache | BE 内共享索引、元数据缓存及本地磁盘数据缓存 |
+| TopN 两阶段读取 | 对向量和全文检索中可延迟的输出列默认开启,由 `enable_lance_lazy_materialization` 独立控制
|
| 写入 Lance | 暂不支持 |
| Time Travel | 暂不支持 |
| Hybrid Search | 暂不支持 |
## Lance 版本与兼容性
-Doris BE 数据读取器使用 `lance-c v0.1.8` 构建,其内置的 Lance Rust crates 固定在 Lance commit
`e934cc2c`。Doris FE 使用 `lance-java` 客户端读取 Namespace 和数据集元数据,版本为
`9.1.0-beta.3`(同一 Lance commit)。这些版本表示 Doris 集成的读取器实现版本,与数据集中记录的 Lance
`data_storage_version` 不是同一个概念。
+Doris BE 数据读取器使用 `lance-c v0.1.9` 加 Doris 补丁构建,补丁将其内置的 Lance Rust crates 升级到
`11.0.0`(commit `ab6b5bbe`)。Doris FE 使用 `org.lance:lance-core:11.0.0` 读取
Namespace 和数据集元数据,FE 与 BE 的 Lance 版本统一为 `11.0.0`。Dataset 必须同时满足 FE 元数据加载和 BE
数据读取的兼容性要求。这些实现版本与数据集中记录的 Lance `data_storage_version` 不是同一个概念。
当前读取器的文件格式兼容情况如下:
@@ -693,7 +695,7 @@ ORDER BY _distance ASC, user_id;
### 支持的向量索引类型
-当前内置 `lance-c v0.1.8` 明确支持以下 Lance 向量索引组合:
+当前内置 `lance-c v0.1.9` 明确支持以下 Lance 向量索引组合:
| 索引类型 | 说明 | 主要查询参数 |
|---|---|---|
@@ -760,6 +762,66 @@ ORDER BY _distance ASC, user_id;
`filter` 中引用的列由 Lance 内部读取和计算;如果该列未被 `SELECT` 或其他 Doris 表达式引用,则不需要返回给 Doris。
+## Lance Cache
+
+Lance Cache 复用已读取的索引、元数据和数据文件内容,减少重复查询的读取开销。缓存由每个 BE 独立管理,同一 BE 内的 Lance
查询共享缓存;不同 BE 不共享缓存容量或内容。普通扫描、向量检索、全文检索和两阶段读取的回读都可以复用相应缓存,无需在 `CREATE CATALOG`
中增加属性。
+
+### 缓存类型和范围
+
+| 缓存 | 存储位置 | 缓存内容 |
+|---|---|---|
+| 索引缓存 | BE 内存 | Lance 已加载的索引内容,减少重复加载索引的开销。 |
+| 元数据缓存 | BE 内存 | Lance reader 使用的元数据,减少重复读取和解析。 |
+| 数据缓存 | BE 本地磁盘,附带一个读取块大小的内存缓存层 | Dataset 的 `data/` 目录下直接以 `.lance`
结尾的数据文件,按块缓存读取内容。 |
+
+数据缓存由 Lance reader 内的 Foyer 缓存实现,使用独立目录和容量,通过下面的 `lance_*` BE 参数配置。它不使用 Doris
通用 File Cache 的目录和容量配置。索引文件、manifest 和删除文件不进入该磁盘数据缓存;它们仍使用 Lance 原有的读取及缓存路径。
+
+数据缓存按需填充,不会预先下载整个 Dataset。未命中时读取源存储,并将数据交给后台写入磁盘缓存;首次读取仍会产生源存储 I/O
和缓存填充开销。缓存命中可以减少后续读取的源存储访问,但不消除解码、过滤和排序开销。
+
+### BE 配置
+
+以下参数均为可选项,在每个 BE 的 `be.conf` 中配置,修改后需要重启对应 BE。容量均为单个 BE 的容量,单位为字节。
+
+| 参数 | 类型 | 默认值 | 说明 |
+|---|---|---|---|
+| `lance_index_cache_size_bytes` | Int64 | `10737418240`(10 GiB) | 索引内存缓存容量;设为
`0` 表示零容量。 |
+| `lance_metadata_cache_size_bytes` | Int64 | `1073741824`(1 GiB) |
元数据内存缓存容量;设为 `0` 表示零容量。 |
+| `enable_lance_data_cache` | Boolean | `true` | 是否启用磁盘数据缓存;关闭后仍保留索引和元数据缓存。 |
+| `lance_data_cache_path` | String | `${DORIS_HOME}/lance_data_cache` |
数据缓存目录。BE 进程需要有创建目录和读写文件的权限,不同 BE 进程应使用独立目录。 |
+| `lance_data_cache_disk_capacity_bytes` | Int64 | `107374182400`(100 GiB) |
磁盘缓存容量。必须是 `4096` 的整数倍,且至少为读取块大小的两倍。 |
+| `lance_data_cache_read_block_size_bytes` | Int64 | `1048576`(1 MiB) |
数据缓存的读取块大小。必须为正数且是 `4096` 的整数倍;同时决定数据缓存内存层的容量。 |
+
+例如,显式配置默认容量,并将缓存放在独立的本地磁盘目录:
+
+```properties
+lance_index_cache_size_bytes = 10737418240
+lance_metadata_cache_size_bytes = 1073741824
+enable_lance_data_cache = true
+lance_data_cache_path = /mnt/ssd/lance_data_cache
+lance_data_cache_disk_capacity_bytes = 107374182400
+lance_data_cache_read_block_size_bytes = 1048576
+```
+
+重启 BE 后,首次打开 Lance Dataset 时初始化共享缓存。启用数据缓存时,如果目录不可用或容量、块大小不合法,初始化会失败并导致 Lance
查询报错,不会自动退回到禁用数据缓存的模式。需要关闭磁盘数据缓存时,将 `enable_lance_data_cache` 设为 `false` 后重启 BE。
+
+配置容量时应同时考虑索引缓存、元数据缓存和查询工作内存。上述容量不是 Lance 查询总内存的上限,也不是 BE
进程内存的上限。磁盘缓存还需要本地磁盘空间和文件描述符资源;增大读取块可以减少块数量,但小范围读取可能产生更多额外
I/O。调整读取块大小或磁盘布局时使用新的缓存目录。
+
+### 查看缓存效果
+
+在查询 Profile 的 `LanceReader` 下查看以下计数器:
+
+| 计数器 | 含义 |
+|---|---|
+| `LanceDataCacheBytesReadFromCache` | 经过数据缓存路径、命中缓存并返回给 reader 的逻辑字节数。 |
+| `LanceDataCacheBytesReadFromRemote` | 经过数据缓存路径、未命中后从源存储读取并返回给 reader
的逻辑字节数。源存储也可以是本地文件。 |
+| `LanceIndexPartitionCacheMissLoads` | 因索引分区缓存未命中而加载的分区数,不是整个索引缓存的未命中次数。 |
+
+两个数据缓存字节计数不包含按块读取产生的额外字节,也不覆盖索引、manifest 等绕过数据缓存的
I/O,因此不能用它们代替完整的远端流量统计。数据缓存关闭时,这两个计数为 `0`,不代表没有读取源存储。计数在关闭 Dataset
时收集,应查看查询完成后的 Profile;第二阶段回读也会复用缓存,但这两个扫描计数器不能视为整个查询所有回读 I/O 的合计。
+
+BE 的 `/metrics` 还提供以 `doris_be_lance_session_index_cache_` 和
`doris_be_lance_session_metadata_cache_` 为前缀的指标,后缀分别为
`capacity_bytes`、`usage_bytes`、`entries`、`hits_total` 和
`misses_total`,表示配置容量、当前使用量、条目数、累计命中和累计未命中。这些是 BE 共享缓存指标,初始化共享 Lance Session
后注册,不能直接归属于某一条查询。
+
+比较缓存效果时,应使用相同 Dataset 版本和查询参数,确保查询实际执行并落到相同 BE,同时记录首次读取和重复读取的耗时、缓存计数及源存储
I/O。只查看总耗时不足以区分缓存收益与索引搜索、解码或第二阶段回读的开销。
+
## TopN 两阶段读取和延迟物化
`vector_search()` 和 `full_text_search()` 通常会生成多于最终 `top_k` 的候选行。如果在搜索阶段就读取
`title`、`payload` 等较宽的输出列,大部分数据会在 TopN 排序后被丢弃。两阶段读取会延迟读取这些列:第一阶段只读取过滤、排序和 TopN
所需的列;全局 TopN 完成后,第二阶段仅为最终保留的行读取其他输出列。
@@ -775,14 +837,14 @@ ORDER BY _distance ASC, user_id;
满足以下条件时,Doris 才会使用两阶段读取:
-1. `topn_lazy_materialization_threshold` 大于 `0`,默认值为 `1024`。
-2. `top_k` 不超过该阈值。
+1. 查询通过 `vector_search()` 或 `full_text_search()` 读取 Lance,且执行计划中存在可进行延迟物化的
TopN。普通 Lance 表扫描和 Lance 文件 TVF 当前不适用此开关。
+2. Boolean 类型的会话变量 `enable_lance_lazy_materialization` 为 `true`,默认开启。
3. 查询至少包含一个可以延迟读取的顶层列。仅用于最终 `SELECT` 输出的列可以延迟;Post-filter、`ORDER BY` 或其他 TopN
前表达式使用的列必须在第一阶段读取。嵌套子列当前不能延迟读取。
例如,以下查询中的 `category` 必须在第一阶段用于 Post-filter,而 `user_id`、`title` 和 `payload` 可以在
TopN 完成后读取:
```sql
-SET topn_lazy_materialization_threshold = 1024;
+SET enable_lance_lazy_materialization = true;
SELECT user_id, title, payload, _distance
FROM vector_search(
@@ -797,15 +859,19 @@ WHERE category = 'book';
TVF `filter` 中引用的 Prefilter 列由 Lance 在搜索内部使用,不会仅因为出现在 `filter`
字符串中就作为第一阶段结果列返回给 Doris。
+### 验证是否生效
+
+在上述查询前加上 `EXPLAIN VERBOSE`。两阶段读取生效时,计划中可见 `VMaterializeNode`,其中
`column_descs_lists` 列出第二阶段回读的列。关闭开关后,对同一条简单检索查询再次执行 `EXPLAIN
VERBOSE`,对应的物化节点应消失。如果开启后仍未出现,应检查输出列是否参与过滤、排序或其他 TopN 前计算,以及计划是否支持该优化。
+
### 关闭两阶段读取
设置以下会话变量可以关闭两阶段读取:
```sql
-SET topn_lazy_materialization_threshold = -1;
+SET enable_lance_lazy_materialization = false;
```
-当 `top_k` 大于阈值或没有可延迟列时,Doris 会自动使用单阶段读取,通常不需要手动关闭。以下情况可以考虑关闭并进行性能对比:
+没有可延迟列或计划不支持该优化时,Doris 会使用单阶段读取。Lance 不会仅因为 `top_k`
较大就自动关闭两阶段读取;以下情况可以考虑关闭并进行性能对比:
- `top_k` 很大,第二阶段仍需读取大部分候选行。
- 查询只返回少量窄列,两阶段能够减少的 I/O 很少。
diff --git a/versioned_docs/version-4.x/lakehouse/catalogs/lance-catalog.mdx
b/versioned_docs/version-4.x/lakehouse/catalogs/lance-catalog.mdx
index 77800271e98..ee93c78be40 100644
--- a/versioned_docs/version-4.x/lakehouse/catalogs/lance-catalog.mdx
+++ b/versioned_docs/version-4.x/lakehouse/catalogs/lance-catalog.mdx
@@ -42,13 +42,15 @@ Doris currently provides read-only access to Lance.
Creating, writing, updating,
| File TVFs | Supports querying Lance datasets directly through `s3()` and
`local()` |
| Vector search | Uses physical Lance index segments as parallel splits, keeps
uncovered Fragments as Flat Search splits, and performs a Doris global Top-K
merge |
| Full-text search | Uses existing Lance FTS inverted indexes through
`full_text_search()`, supports Match OR/AND and Phrase queries, and performs a
Doris global Top-K merge |
+| Lance Cache | Shares index and metadata caches and a local disk data cache
within each BE |
+| Two-phase TopN read | Enabled by default for eligible output columns in
vector and full-text searches; controlled independently by
`enable_lance_lazy_materialization` |
| Writing to Lance | Not supported |
| Time Travel | Not supported |
| Hybrid Search | Not supported |
## Lance Version and Compatibility
-The Doris BE data reader is built with `lance-c v0.1.8`, whose embedded Lance
Rust crates are pinned to Lance commit `e934cc2c`. The Doris FE reads Namespace
and dataset metadata with the `lance-java` client at version `9.1.0-beta.3`
(the same Lance commit). These versions identify the reader implementations
integrated with Doris. They are different from the Lance `data_storage_version`
recorded in a dataset.
+The Doris BE data reader is built with `lance-c v0.1.9` plus Doris patches,
which upgrade its embedded Lance Rust crates to `11.0.0` (commit `ab6b5bbe`).
The Doris FE reads Namespace and dataset metadata with
`org.lance:lance-core:11.0.0`, aligning the FE and BE on Lance `11.0.0`. A
Dataset must be compatible with both FE metadata loading and BE data reading.
These implementation versions are different from the Lance
`data_storage_version` recorded in a dataset.
The following table describes the file-format compatibility of this reader:
@@ -693,7 +695,7 @@ These defaults correspond to the Lance Scanner behavior
currently integrated wit
### Supported Vector Index Types
-The embedded `lance-c v0.1.8` explicitly supports the following Lance vector
index combinations:
+The embedded `lance-c v0.1.9` explicitly supports the following Lance vector
index combinations:
| Index type | Description | Main query parameters |
|---|---|---|
@@ -760,6 +762,66 @@ If `user_id > 100` must also participate in candidate
generation, include it in
Lance reads and evaluates columns referenced only by `filter` internally. If
such a column is not referenced by `SELECT` or another Doris expression, it
does not have to be returned to Doris.
+## Lance Cache
+
+Lance Cache reuses index, metadata, and data-file content to reduce repeated
reads. Each BE manages its own cache, shared by Lance queries on that BE. Cache
capacity and content are not shared across BEs. Ordinary scans, vector search,
full-text search, and second-phase fetches can reuse the corresponding caches
without additional `CREATE CATALOG` properties.
+
+### Cache Types and Scope
+
+| Cache | Storage | Cached content |
+|---|---|---|
+| Index cache | BE memory | Loaded Lance index content, reducing repeated
index loads. |
+| Metadata cache | BE memory | Metadata used by the Lance reader, reducing
repeated reads and parsing. |
+| Data cache | BE local disk, with an in-memory tier sized to one read block |
Data read from files ending in `.lance` directly under a Dataset's `data/`
directory, cached in blocks. |
+
+The data cache uses Foyer within the Lance reader, with its own directory and
capacity configured through the `lance_*` BE parameters below. It does not use
Doris's general File Cache directory or capacity settings. Index files,
manifests, and deletion files bypass this disk data cache and continue to use
Lance's existing read and cache paths.
+
+The data cache fills on demand without downloading the entire Dataset in
advance. On a miss, it reads from the source storage and enqueues the data for
background disk-cache writes. The first read still incurs source I/O and
cache-fill overhead. Cache hits can reduce subsequent source reads, but do not
eliminate decoding, filtering, or sorting costs.
+
+### BE Configuration
+
+All parameters below are optional. Set them in each BE's `be.conf` and restart
that BE for changes to take effect. Capacities are per BE and expressed in
bytes.
+
+| Parameter | Type | Default | Description |
+|---|---|---|---|
+| `lance_index_cache_size_bytes` | Int64 | `10737418240` (10 GiB) | Index
memory-cache capacity. Set to `0` for zero capacity. |
+| `lance_metadata_cache_size_bytes` | Int64 | `1073741824` (1 GiB) | Metadata
memory-cache capacity. Set to `0` for zero capacity. |
+| `enable_lance_data_cache` | Boolean | `true` | Enables the disk data cache.
Disabling it preserves the index and metadata caches. |
+| `lance_data_cache_path` | String | `${DORIS_HOME}/lance_data_cache` |
Data-cache directory. The BE process needs permission to create the directory
and read/write files. Use separate directories for different BE processes. |
+| `lance_data_cache_disk_capacity_bytes` | Int64 | `107374182400` (100 GiB) |
Disk-cache capacity. Must be a multiple of `4096` and at least twice the read
block size. |
+| `lance_data_cache_read_block_size_bytes` | Int64 | `1048576` (1 MiB) |
Data-cache read block size. Must be positive and a multiple of `4096`. Also
sets the capacity of the data cache's in-memory tier. |
+
+For example, explicitly configure the default capacities and place the cache
in a separate local disk directory:
+
+```properties
+lance_index_cache_size_bytes = 10737418240
+lance_metadata_cache_size_bytes = 1073741824
+enable_lance_data_cache = true
+lance_data_cache_path = /mnt/ssd/lance_data_cache
+lance_data_cache_disk_capacity_bytes = 107374182400
+lance_data_cache_read_block_size_bytes = 1048576
+```
+
+After the BE restarts, the shared cache initializes when the first Lance
Dataset is opened. With the data cache enabled, an unavailable directory or
invalid capacity or block size causes initialization to fail and Lance queries
to report an error. There is no automatic fallback to running without the data
cache. To disable the disk data cache, set `enable_lance_data_cache` to `false`
and restart the BE.
+
+Budget for index and metadata caches alongside query working memory. These
capacities do not limit total Lance query memory or BE process memory. The disk
cache also consumes local disk space and file descriptors. Larger read blocks
reduce the number of blocks but can increase extra I/O for small reads. Use a
new cache directory when changing the read block size or disk layout.
+
+### Checking Cache Effectiveness
+
+Inspect the following counters under `LanceReader` in the query Profile:
+
+| Counter | Meaning |
+|---|---|
+| `LanceDataCacheBytesReadFromCache` | Logical bytes returned to the reader
from cache hits through the data-cache path. |
+| `LanceDataCacheBytesReadFromRemote` | Logical bytes returned to the reader
from source storage after data-cache misses. The source can also be a local
file. |
+| `LanceIndexPartitionCacheMissLoads` | Index partitions loaded because of
partition-cache misses, rather than the miss count for the entire index cache. |
+
+The two data-cache byte counters exclude extra bytes caused by block-aligned
reads and I/O that bypasses the data cache, such as index and manifest reads.
They are not complete remote-traffic counters. Both are `0` when the data cache
is disabled, which does not imply that no source reads occurred. Statistics are
collected when the Dataset closes, so inspect the completed query Profile.
Second-phase fetches also reuse the cache, but these scan counters are not a
query-wide total of all f [...]
+
+The BE `/metrics` endpoint also exposes metrics prefixed with
`doris_be_lance_session_index_cache_` and
`doris_be_lance_session_metadata_cache_`. The suffixes `capacity_bytes`,
`usage_bytes`, `entries`, `hits_total`, and `misses_total` represent configured
capacity, current usage, entry count, cumulative hits, and cumulative misses.
These metrics are registered after the shared Lance Session initializes and
describe the BE-wide cache, rather than an individual query.
+
+To compare cache effectiveness, use the same Dataset version and query
parameters, ensure queries actually execute on the same BEs, and record
first-read and repeated-read latency, cache counters, and source I/O. Total
latency alone does not distinguish cache benefits from index search, decoding,
or second-phase fetch costs.
+
## Two-Phase TopN Read and Lazy Materialization
`vector_search()` and `full_text_search()` commonly produce more candidate
rows than the final `top_k`. Reading wide output columns such as `title` or
`payload` during the search wastes work because most candidate rows are
discarded by TopN. Two-phase reading defers these columns: Phase 1 reads only
the columns required for filtering, ordering, and TopN; after global TopN,
Phase 2 reads the remaining output columns only for the retained rows.
@@ -775,14 +837,16 @@ This reduces storage I/O, network transfer, and memory
usage. The benefit is usu
Doris uses two-phase reading only when all of the following conditions are met:
-1. `topn_lazy_materialization_threshold` is greater than `0`. Its default
value is `1024`.
-2. `top_k` does not exceed the threshold.
+1. The query reads Lance through `vector_search()` or `full_text_search()` and
its plan contains a TopN eligible for lazy materialization. This switch does
not currently apply to ordinary Lance table scans or Lance file TVFs.
+2. The Boolean session variable `enable_lance_lazy_materialization` is `true`,
its default value.
3. At least one top-level column can be deferred. A column used only by the
final `SELECT` projection can be deferred. A column used by a Post-filter,
`ORDER BY`, or another expression before TopN must be read in Phase 1. Nested
subcolumns cannot currently be deferred.
+`enable_lance_lazy_materialization` is independent of
`topn_lazy_materialization_threshold`: Lance can still use two-phase reading
when the latter is `-1` or `top_k` exceeds that threshold. Other tables that
support lazy materialization continue to follow the general threshold. Enabling
the switch allows the optimization; the plan structure and eligible columns
still determine whether it applies.
+
In the following query, `category` must be read in Phase 1 for the
Post-filter, while `user_id`, `title`, and `payload` can be fetched after TopN:
```sql
-SET topn_lazy_materialization_threshold = 1024;
+SET enable_lance_lazy_materialization = true;
SELECT user_id, title, payload, _distance
FROM vector_search(
@@ -797,15 +861,19 @@ WHERE category = 'book';
A Prefilter column referenced in the TVF `filter` is used internally by Lance.
Its presence in the `filter` string alone does not make it a Phase-1 result
column returned to Doris.
+### Verifying the Plan
+
+Prefix the query above with `EXPLAIN VERBOSE`. When two-phase reading is
active, the plan includes `VMaterializeNode`, whose `column_descs_lists` lists
the columns fetched in Phase 2. Disable the switch and run `EXPLAIN VERBOSE`
again for the same simple search query; the corresponding materialization node
should disappear. If it is absent with the switch enabled, check whether the
output columns are used in filtering, ordering, or other computations before
TopN, and whether the plan sup [...]
+
### Disabling Two-Phase Reading
Use the following session setting to disable two-phase reading:
```sql
-SET topn_lazy_materialization_threshold = -1;
+SET enable_lance_lazy_materialization = false;
```
-Doris automatically uses a single-phase read when `top_k` exceeds the
threshold or no column can be deferred, so manual disabling is usually
unnecessary. Consider disabling it and comparing performance in the following
cases:
+Doris uses a single-phase read when no column can be deferred or the plan does
not support the optimization. A large `top_k` alone does not automatically
disable two-phase reading for Lance. Consider disabling it and comparing
performance in the following cases:
- `top_k` is large, so Phase 2 still reads most candidate rows.
- The query returns only a few narrow columns, leaving little I/O for
two-phase reading to save.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]