You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by el...@apache.org on 2026/04/07 03:57:52 UTC

(doris-website) branch master updated: refactor row store document (#3523)

This is an automated email from the ASF dual-hosted git repository.

eldenmoon 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 e773370444b refactor row store document (#3523)
e773370444b is described below

commit e773370444bea1aae1c48b8067c44823d7bd4463
Author: lihangyu <li...@selectdb.com>
AuthorDate: Tue Apr 7 11:57:45 2026 +0800

    refactor row store document (#3523)
    
    ## Versions
    
    - [x] dev
    - [x] 4.x
    - [x] 3.x
    - [x] 2.1
    
    ## Languages
    
    - [ ] Chinese
    - [ ] English
    
    ## Docs Checklist
    
    - [ ] Checked by AI
    - [ ] Test Cases Built
---
 docs/table-design/row-store.md                     | 122 +++++++++++++-------
 .../current/table-design/row-store.md              | 119 +++++++++++++-------
 .../version-2.0/table-design/row-store.md          |  23 ++--
 .../version-2.1/table-design/row-store.md          |  34 +++---
 .../version-3.x/table-design/row-store.md          | 120 +++++++++++++-------
 .../version-4.x/table-design/row-store.md          | 119 +++++++++++++-------
 .../version-2.0/table-design/row-store.md          |  21 ++--
 .../version-2.1/table-design/row-store.md          |  31 +++---
 .../version-3.x/table-design/row-store.md          | 123 ++++++++++++++-------
 .../version-4.x/table-design/row-store.md          | 122 +++++++++++++-------
 10 files changed, 545 insertions(+), 289 deletions(-)

diff --git a/docs/table-design/row-store.md b/docs/table-design/row-store.md
index 85a81d92859..809c84e8e90 100644
--- a/docs/table-design/row-store.md
+++ b/docs/table-design/row-store.md
@@ -2,54 +2,88 @@
 {
     "title": "Hybrid Row-Columnar Storage",
     "language": "en",
-    "description": "Doris uses columnar storage by default, with each column stored contiguously."
+    "description": "Doris hybrid row-columnar storage enables row-oriented storage alongside columnar storage, reducing IOPS for point queries on wide tables."
 }
 ---
 
-## Hybrid Row-Columnar Storage
+## Overview
 
-Doris uses columnar storage by default, with each column stored contiguously. Columnar storage offers excellent performance for analytical scenarios (such as aggregation, filtering, sorting, etc.), as it only reads the necessary columns, reducing unnecessary IO. However, in point query scenarios (such as `SELECT *`), all columns need to be read, requiring an IO operation for each column, which can lead to IOPS becoming a bottleneck, especially for wide tables with many columns (e.g., hun [...]
+Doris uses columnar storage by default, where each column is stored contiguously. Columnar storage performs well in analytical scenarios (aggregation, filtering, sorting, etc.) because it reads only the required columns. However, when a query needs all columns — such as `SELECT *` in point query scenarios — each column requires a separate IO operation, making IOPS a bottleneck. This is especially noticeable on wide tables with hundreds of columns.
 
-To address the IOPS bottleneck in point query scenarios, starting from version 2.0.0, Doris supports Hybrid Row-Columnar Storage. When users create tables, they can specify whether to enable row storage. With row storage enabled, each row only requires one IO operation for point queries (such as `SELECT *`), significantly improving performance.
+To solve this, Doris supports **Hybrid Row-Columnar Storage** since version 2.0.0. When row storage is enabled at table creation, all columns of a row are concatenated into a single additional column using a compact binary format. A point query then reads a complete row in one IO operation instead of one IO per column, significantly reducing IOPS and improving latency.
 
-The principle of row storage is that an additional column is added during storage. This column concatenates all the columns of the corresponding row and stores them using a special binary format.
+## Use Cases
 
-## Syntax
+Row storage is recommended in the following scenarios:
 
-When creating a table, specify whether to enable row storage, which columns to enable row storage for, and the storage compression unit size page_size in the table's PROPERTIES.
+- **High-concurrency primary key point queries** on Unique Key merge-on-write (MOW) tables, where each query looks up a specific row by the full primary key.
+- **Wide-table `SELECT *` queries** on Duplicate or MOW tables where only a small number of rows are returned (TOPN pattern).
 
-1. Whether to enable row storage: defaults to false (not enabled).
-``` 
-"store_row_column" = "true"
-```
+If your workload is primarily analytical (aggregation, complex filtering on a few columns), columnar storage alone is usually sufficient.
 
-2. Which columns to enable row storage for:if `"store_row_column" = "true"`, all columns are enabled by default. If you need to specify that only some columns are enabled for row storage, set the row_store_columns parameter (afer version 3.0), formatted as a comma-separated list of column names.
-``` 
-"row_store_columns" = "column1,column2,column3"
-```
+## Table Properties
 
-3. Row storage page_size: defaults to 16KB.
-``` 
-"row_store_page_size" = "16384"
-```
+Enable and configure row storage through the following `PROPERTIES` when creating a table.
 
-A page is the smallest unit for storage read and write operations, and `page_size` refers to the size of a row-store page. This means that reading a single row requires generating a page IO. The larger this value is, the better the compression effect and the lower the storage space usage. However, the IO overhead during point queries increases, resulting in lower performance (because each IO operation reads at least one page). Conversely, the smaller the value, the higher the storage spa [...]
+| Property | Default | Since | Description |
+|----------|---------|-------|-------------|
+| `"store_row_column" = "true"` | `false` | 2.0 | Enable row storage for **all** columns. |
+| `"row_store_columns" = "col1,col2,..."` | All columns | 3.0 | Enable row storage for **specified columns only**. When this property is set, `store_row_column` is implicitly enabled. Using selective columns reduces storage overhead compared to storing all columns. |
+| `"row_store_page_size" = "16384"` | `16384` (16 KB) | 2.0 | Size of the row-store page in bytes. A page is the minimum IO unit — reading even a single row requires one page IO. |
 
+**Tuning `row_store_page_size`:**
 
-## Row Store Hit Conditions
+| Goal | Recommended page_size | Trade-off |
+|------|----------------------|-----------|
+| Best point query performance | 4096 (4 KB) or smaller | Higher storage overhead |
+| Balanced (default) | 16384 (16 KB) | — |
+| Minimum storage overhead | 65536 (64 KB) or larger | Higher point query latency |
 
-Row store hit conditions are divided into two scenarios: one is high-concurrency primary key point queries that depend on table attributes and satisfy point query conditions, and the other is single-table `SELECT *` queries. These two query types are explained below.
+## When Row Storage Is Used
 
-- For high-concurrency primary key point queries, the table attributes need to have `"enable_unique_key_merge_on_write" = "true"` (MOW table) and `"store_row_column" = "true"` (all columns are stored separately in the row store, which incurs relatively high storage costs) or `"row_store_columns" = "key,v1,v3,v5,v7"` (only specified columns are stored in the row store). When querying, ensure the `WHERE` clause includes all primary keys with equality conditions connected by `AND`, e.g., `S [...]
+Row storage is triggered in two scenarios. Each has different prerequisites.
 
-- For general non-primary key point queries, to utilize the row store, the table model must be `DUPLICATE` or have `"enable_unique_key_merge_on_write" = "true"` (MOW table) and `"store_row_column" = "true"` (all columns are stored separately in the row store, which incurs relatively high storage costs). Queries satisfying this pattern can hit the row store with `SELECT * FROM tbl [WHERE XXXXX] ORDER BY XXX LIMIT N`, where the content in square brackets is an optional query condition. Not [...]
+### Scenario 1: High-Concurrency Primary Key Point Query (Short-Circuit)
 
+This optimization applies when **all** of the following conditions are met:
 
-## Usage Examples
+1. The table is a **Unique Key MOW table** (`"enable_unique_key_merge_on_write" = "true"`).
+2. Row storage is enabled via `"store_row_column" = "true"` or `"row_store_columns" = "..."`.
+3. The `WHERE` clause contains **equality conditions on all primary key columns**, joined by `AND`.
 
-The following example creates a table with 8 columns, where the 5 columns `key, v1, v3, v5, v7` are enabled for row store, and the `page_size` is set to 4KB for high-concurrency point query performance.
+Example queries:
 
+```sql
+-- Full row retrieval
+SELECT * FROM tbl WHERE k1 = 1 AND k2 = 2;
+
+-- Partial column retrieval
+SELECT v1, v2 FROM tbl WHERE k1 = 1 AND k2 = 2;
 ```
+
+**Partial column coverage:** If the row store contains only some columns (e.g., `v1`) but the query also requests columns not in the row store (e.g., `v2`), Doris fetches the missing columns from the column store. The columns in the row store are still read efficiently, while the remaining columns incur normal columnar IO.
+
+**Verification:** Run `EXPLAIN` on the query and check for the `SHORT-CIRCUIT` marker. For details, see [High-Concurrency Point Query](../query-acceleration/high-concurrent-point-query).
+
+### Scenario 2: TOPN Deferred Materialization Query (Fetch Row Store)
+
+This optimization applies when **all** of the following conditions are met:
+
+1. The table is a **Duplicate** table, or a **Unique Key MOW table** (`"enable_unique_key_merge_on_write" = "true"`).
+2. **All columns** must be in the row store (`"store_row_column" = "true"`).
+3. The query follows the pattern `SELECT * FROM tbl [WHERE ...] ORDER BY ... LIMIT N`.
+4. The query must be `SELECT *` — selecting specific columns is not supported for this optimization.
+5. The TOPN deferred materialization optimization must be triggered. For details, see [TOPN Query Optimization](../query-acceleration/optimization-technology-principle/topn-optimization).
+
+**Verification:** Run `EXPLAIN` on the query and check for both the `FETCH ROW STORE` and `OPT TWO PHASE` markers.
+
+## Examples
+
+### Example 1: Unique Key MOW Table with Selective Row Store Columns
+
+Create a table with 8 columns, enable row storage for 5 selected columns, and set `page_size` to 4 KB for optimal point query performance:
+
+```sql
 CREATE TABLE `tbl_point_query` (
     `k` int(11) NULL,
     `v1` decimal(27, 9) NULL,
@@ -71,19 +105,22 @@ PROPERTIES (
 );
 ```
 
-Query 1
+Point query on the row-stored columns:
 
+```sql
+SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100;
 ```
-SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100
-```
-The `EXPLAIN` output for the above statement should include the `SHORT-CIRCUIT` marker. For more details on point query usage, refer to [High-Concurrency Point Query](../query-acceleration/high-concurrent-point-query).
 
-The following example demonstrates how a `DUPLICATE` table can meet row store query conditions.
+Run `EXPLAIN` on this query — the output should include the `SHORT-CIRCUIT` marker. For more details, see [High-Concurrency Point Query](../query-acceleration/high-concurrent-point-query).
 
-```
+### Example 2: Duplicate Table with Full Row Store
+
+Create a Duplicate table with row storage enabled for all columns:
+
+```sql
 CREATE TABLE `tbl_duplicate` (
     `k` int(11) NULL,
-    `v1` string NULw
+    `v1` string NULL
 ) ENGINE=OLAP
 DUPLICATE KEY(`k`)
 COMMENT 'OLAP'
@@ -95,17 +132,20 @@ PROPERTIES (
 );
 ```
 
-`"store_row_column" = "true"` is required.
+:::note
+`"store_row_column" = "true"` is required for Duplicate tables. The `row_store_columns` property is not supported with Duplicate tables — all columns are stored in the row store.
+:::
 
-Query 2 (Note: It must hit TOPN query optimization and must be `SELECT *`)
+TOPN query using row storage:
 
-```
-SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10
+```sql
+SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10;
 ```
 
-The `EXPLAIN` output for the above statement should include the `FETCH ROW STORE` marker and the `OPT TWO PHASE` marker.
+Run `EXPLAIN` on this query — the output should include both the `FETCH ROW STORE` marker and the `OPT TWO PHASE` marker.
 
-## Notice
+## Limitations
 
-1. Enabling row storage will increase the storage space used. The increase in storage space is related to the data characteristics and is generally 2 to 10 times the size of the original table. The exact space usage needs to be tested with actual data.
-2. The `page_size` of row storage also affects the storage space. You can adjust it based on the previous table attribute parameter `row_store_page_size`.
+1. **Storage overhead:** Enabling row storage increases disk usage. Depending on data characteristics, the additional storage is typically 2–10× the original table size. Test with actual data to measure the impact.
+2. **page_size affects storage:** A smaller `row_store_page_size` improves point query performance but increases storage overhead. See the [Table Properties](#table-properties) section for tuning guidance.
+3. **ALTER not supported:** Modifying the `store_row_column` and `row_store_columns` properties via `ALTER TABLE` is not supported.
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/row-store.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/row-store.md
index deda707aad0..9a9a7b154ac 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/row-store.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/row-store.md
@@ -2,52 +2,88 @@
 {
     "title": "行列混存",
     "language": "zh-CN",
-    "description": "Doris 默认采用列式存储,每个列连续存储,在分析场景(如聚合,过滤,排序等)有很好的性能,因为只需要读取所需要的列减少不必要的 IO。但是在点查场景(比如 SELECT ),需要读取所有列,每个列都需要一次 IO 导致 IOPS 成为瓶颈,特别对列多的宽表(比如上百列)尤为明显。"
+    "description": "Doris 行列混存功能在列存基础上增加行存,降低宽表点查场景的 IOPS 开销。"
 }
 ---
 
-## 行列混存介绍
+## 概述
 
-Doris 默认采用列式存储,每个列连续存储,在分析场景(如聚合,过滤,排序等)有很好的性能,因为只需要读取所需要的列减少不必要的 IO。但是在点查场景(比如 `SELECT *`),需要读取所有列,每个列都需要一次 IO 导致 IOPS 成为瓶颈,特别对列多的宽表(比如上百列)尤为明显。
+Doris 默认采用列式存储,每个列连续存储。列存在分析场景(聚合、过滤、排序等)表现优异,因为只需读取所需的列。但在点查场景(如 `SELECT *`)中需要读取所有列,每列一次 IO,在列数较多的宽表(如上百列)上 IOPS 会成为瓶颈。
 
-为了解决点查场景 IOPS 的瓶颈问题,Doris 2.0.0 版本开始支持行列混存,用户建表时指定开启行存后,点查(比如 `SELECT *`)每一行只需要一次 IO,在宽表列很多的情况下性能有数量级提升。
+为此,Doris 从 2.0.0 版本开始支持**行列混存**。在建表时开启行存后,系统会在存储时增加一个额外的列,将该行所有列拼接为紧凑二进制格式存储。点查时只需一次 IO 即可读取完整行数据,大幅降低 IOPS、提升查询延迟。
 
-行存的原理是在存储时增加了一个额外的列,这个列将对应行的所有列拼接起来采用特殊的二进制格式存储。
+## 适用场景
 
-## 使用语法
+以下场景推荐开启行存:
 
-建表时在表的 PROPERTIES 中指定是否开启行存,哪些列开启行存,行存的存储压缩单元大小 page_size。
+- **主键高并发点查**:在 Unique Key Merge-On-Write(MOW)表上,根据完整主键查找特定行。
+- **宽表 `SELECT *` 查询**:在 Duplicate 表或 MOW 表上,仅返回少量行的 TOPN 查询。
 
-1. 是否开启行存:默认为 false 不开启
-```
-"store_row_column" = "true"
-```
+如果业务以分析查询为主(聚合、对少数列的复杂过滤等),通常仅列存即可满足需求。
 
-2. 哪些列开启行存:如果 `"store_row_column" = "true"`,默认所有列开启行存,若需要指定部分列开启行存,设置 row_store_columns 参数(3.0 之后的版本),格式为逗号分割的列名
-```
-"row_store_columns" = "column1,column2,column3"
-```
+## 建表配置
 
-3. 行存 page_size:默认为 16KB。
-```
-"row_store_page_size" = "16384"
-```
+通过 `CREATE TABLE` 的 `PROPERTIES` 设置行存相关参数:
+
+| 参数 | 默认值 | 支持版本 | 说明 |
+|------|--------|---------|------|
+| `"store_row_column" = "true"` | `false` | 2.0+ | 对**所有列**开启行存。 |
+| `"row_store_columns" = "col1,col2,..."` | 全部列 | 3.0+ | 仅对**指定列**开启行存。设置此参数时 `store_row_column` 隐式启用。相比全量行存可显著降低存储开销。 |
+| `"row_store_page_size" = "16384"` | `16384`(16 KB) | 2.0+ | 行存 page 大小(字节)。page 是最小 IO 单元——即使只读一行也需产生一个 page 的 IO。 |
 
-page 是存储读写的最小单元,page_size 是行存 page 的大小,也就是说读一行也需要产生一个 page 的 IO。这个值越大压缩效果越好存储空间占用越低,但是点查时 IO 开销越大性能越低(因为一次 IO 至少读一个 page),反过来值越小存储空间越高,点查性能越好。默认值 16KB 是大多数情况下比较均衡的选择,如果更偏向查询性能可以配置较小的值比如 4KB 甚至更低,如果更偏向存储空间可以配置较大的值比如 64KB 甚至更高。
+**`row_store_page_size` 调优建议:**
+
+| 优化目标 | 建议 page_size | 权衡 |
+|---------|---------------|------|
+| 最佳点查性能 | 4096(4 KB)或更小 | 存储开销更高 |
+| 均衡(默认) | 16384(16 KB) | — |
+| 最小存储开销 | 65536(64 KB)或更大 | 点查延迟更高 |
 
 ## 行存命中条件
-行存命中条件分成两种情况,一种是高并发主键点查需要依赖表的属性以及查询满足点查条件,另一种是单表 SELECT * 查询,下面针对这两种查询进行说明。
 
-- 对于主键高并发点查,建表属性需要开启 `"enable_unique_key_merge_on_write" = "true"`(MOW 表)以及 `"store_row_column" = "true"`(所有列都会在行存中单独额外存一份,存储代价相对较高)或者 `"row_store_columns" = "key,v1,v3,v5,v7"`(只会存储询部分列到行存中)。查询的时候注意 where 条件中需要有所有的主键等值并且是 AND,例如`SELECT * FROM tbl WHERE k1 = 1 AND k2 = 2` 或者查询部分列 `SELECT v1, v2 FROM tbl WHERE k1 = 1 AND k2 = 2`,如果行存只包含了部分列(v1),但是查询的列不在行存中(例如 v2),那么将会从列存中查询剩余的列,该例子中 v1 将会从行存查询,而 v2 会从列存中查询(列存的 page size 更大,会有更多的读放大),通过 EXPLAIN 可以确认是否命中主键高并发点查优化,更多点查的使用请参考 [高并发点查](../query- [...]
+行存在以下两种场景中被触发,各有不同的前提条件。
 
+### 场景一:主键高并发点查(Short-Circuit)
 
-- 对于一般的非主键点查,如果想要走行存那么表模型 DUPLICATE 或者开启`"enable_unique_key_merge_on_write" = "true"`(MOW 表),以及及 `"store_row_column" = "true"`(所有列都会在行存中单独额外存一份,存储代价相对较高)。查询满足这种模式将可以命中行存`SELECT * FROM tble [WHERE XXXXX] ORDER BY XXX LIMIT N` 方括号中的是可选查询条件,注意目前只能是`SELECT *`,且需要命中 TOPN 的延迟物化优化,具体参考[TOPN 查询优化](../query-acceleration/optimization-technology-principle/topn-optimization),即命中`OPT TWO PHASE`。最后通过 EXPLAIN 查看是否有有`FETCH ROW STORE`相应的标记即可确认命中行存
+需要**同时满足**以下所有条件:
 
-## 使用示例
+1. 表为 **Unique Key MOW 表**(`"enable_unique_key_merge_on_write" = "true"`)。
+2. 已通过 `"store_row_column" = "true"` 或 `"row_store_columns" = "..."` 开启行存。
+3. `WHERE` 子句包含**所有主键列的等值条件**,用 `AND` 连接。
 
-下面的例子创建一个 8 列的表,其中 "key,v1,v3,v5,v7" 这 5 列开启行存,为了高并发点查性能配置 page_size 为 4KB。
+查询示例:
 
+```sql
+-- 查询全部列
+SELECT * FROM tbl WHERE k1 = 1 AND k2 = 2;
+
+-- 查询部分列
+SELECT v1, v2 FROM tbl WHERE k1 = 1 AND k2 = 2;
 ```
+
+**部分列行存的处理:** 如果行存只包含部分列(如 `v1`),但查询还请求了不在行存中的列(如 `v2`),Doris 会从列存中读取缺失的列。行存中的列仍然高效读取,其余列执行正常的列存 IO。
+
+**验证方法:** 对查询执行 `EXPLAIN`,检查输出中是否包含 `SHORT-CIRCUIT` 标记。详见 [高并发点查](../query-acceleration/high-concurrent-point-query)。
+
+### 场景二:TOPN 延迟物化查询(Fetch Row Store)
+
+需要**同时满足**以下所有条件:
+
+1. 表为 **Duplicate 表**或 **Unique Key MOW 表**(`"enable_unique_key_merge_on_write" = "true"`)。
+2. 必须对**所有列**开启行存(`"store_row_column" = "true"`)。
+3. 查询满足 `SELECT * FROM tbl [WHERE ...] ORDER BY ... LIMIT N` 模式。
+4. 必须是 `SELECT *`——不支持选择特定列。
+5. 需要命中 TOPN 延迟物化优化。详见 [TOPN 查询优化](../query-acceleration/optimization-technology-principle/topn-optimization)。
+
+**验证方法:** 对查询执行 `EXPLAIN`,检查输出中是否同时包含 `FETCH ROW STORE` 和 `OPT TWO PHASE` 标记。
+
+## 使用示例
+
+### 示例一:Unique Key MOW 表 + 部分列行存
+
+创建一个 8 列的表,对其中 5 列开启行存,设置 `page_size` 为 4 KB 以获得最佳点查性能:
+
+```sql
 CREATE TABLE `tbl_point_query` (
     `k` int(11) NULL,
     `v1` decimal(27, 9) NULL,
@@ -69,16 +105,19 @@ PROPERTIES (
 );
 ```
 
-查询 1
+执行点查:
 
+```sql
+SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100;
 ```
-SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100
-```
-explain 上述语句应该包含 `SHORT-CIRCUIT` 相应的标记。更多点查的使用请参考 [高并发点查](../query-acceleration/high-concurrent-point-query) 。
 
-下面这个例子展示了 DUPLICATE 表怎么命中行存查询条件
+对该语句执行 `EXPLAIN`,输出中应包含 `SHORT-CIRCUIT` 标记。更多用法详见 [高并发点查](../query-acceleration/high-concurrent-point-query)。
 
-```
+### 示例二:Duplicate 表 + 全量行存
+
+创建一个 Duplicate 表,对所有列开启行存:
+
+```sql
 CREATE TABLE `tbl_duplicate` (
     `k` int(11) NULL,
     `v1` string NULL
@@ -92,17 +131,21 @@ PROPERTIES (
     "row_store_page_size" = "4096"
 );
 ```
-` "store_row_column" = "true",` 是必须的
 
-查询 2(注意命中 TOPN 查询优化以及需要是`SELECT *`)
+:::note
+Duplicate 表必须设置 `"store_row_column" = "true"`,不支持 `row_store_columns` 指定部分列——所有列均会存入行存。
+:::
 
+执行 TOPN 查询:
+
+```sql
+SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10;
 ```
-SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10
-```
-explain 上述语句应该包含`FETCH ROW STORE` 相应的标记,以及`OPT TWO PHASE`标记
 
+对该语句执行 `EXPLAIN`,输出中应同时包含 `FETCH ROW STORE` 标记和 `OPT TWO PHASE` 标记。
 
 ## 注意事项
 
-1. 开启行存后占用的存储空间会增加,存储空间的增加和数据特点有关,一般是原来表的 2 到 10 倍,具体空间占用需要使用实际数据测试。
-2. 行存的 page_size 对存储空间的也有影响,可以根据前面的表属性参数 `row_store_page_size` 说明进行调整。
+1. **存储开销:** 开启行存会增加磁盘使用量。根据数据特点,额外存储通常为原表大小的 2–10 倍。建议使用实际数据测试以评估影响。
+2. **page_size 影响存储:** 较小的 `row_store_page_size` 可提升点查性能,但会增加存储开销。调优建议详见[建表配置](#建表配置)章节。
+3. **不支持 ALTER:** 不支持通过 `ALTER TABLE` 修改 `store_row_column` 和 `row_store_columns` 属性。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.0/table-design/row-store.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.0/table-design/row-store.md
index 88ac1e1c290..a109782e79a 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.0/table-design/row-store.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.0/table-design/row-store.md
@@ -15,17 +15,19 @@ Doris 默认采用列式存储,每个列连续存储,在分析场景(如
 
 ## 使用语法
 
-建表时在表的 PROPERTIES 中指定是否开启行存。
-```
-"store_row_column" = "true"
-```
+建表时在表的 `PROPERTIES` 中指定是否开启行存以及其存储单位大小。
+
+| 参数 | 默认值 | 说明 |
+|---|---|---|
+| `"store_row_column"` | `false` | 对所有列开启行存。 |
+| `"row_store_page_size"` | `16384`(16 KB) | 行存 page 大小(字节)。较小的值适合极致点查性能,但占用更多存储。 |
 
 
 ## 使用示例
 
 下面的例子创建一个 8 列的表,开启行存。
 
-```
+```sql
 CREATE TABLE `tbl_point_query` (
     `key` int(11) NULL,
     `v1` decimal(27, 9) NULL,
@@ -47,15 +49,16 @@ PROPERTIES (
 );
 ```
 
-查询
-```
-SELECT * FROM tbl_point_query WHERE key = 100;
+查询:
+
+```sql
+SELECT * FROM tbl_point_query WHERE key = 100;
 ```
 
-更多点查的使用请参考 [高并发点查](../query-acceleration/high-concurrent-point-query) 。
+更多点查的使用请参考 [高并发点查](../query/high-concurrent-point-query) 。
 
 
 ## 注意事项
 
 1. 开启行存后占用的存储空间会增加,存储空间的增加和数据特点有关,一般是原来表的 2 到 10 倍,具体空间占用需要使用实际数据测试。
-2. 2.0不支持 alter `store_row_column` 属性
\ No newline at end of file
+2. 不支持通过 `ALTER TABLE` 修改 `store_row_column` 属性。
\ No newline at end of file
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/table-design/row-store.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/table-design/row-store.md
index bb6abb932c8..ec4ce5177e4 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/table-design/row-store.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/table-design/row-store.md
@@ -16,26 +16,24 @@ Doris 默认采用列式存储,每个列连续存储,在分析场景(如
 
 ## 使用语法
 
-建表时在表的 PROPERTIES 中指定是否开启行存,哪些列开启行存,行存的存储压缩单元大小 page_size。
+建表时在表的 `PROPERTIES` 中指定是否开启行存,以及行存的存储压缩单元大小 `page_size`。
 
-1. 是否开启行存:默认为 false 不开启
-```
-"store_row_column" = "true"
-```
-
-2. 行存 page_size:默认为 16KB。
-```
-"row_store_page_size" = "16384"
-```
+| 参数 | 默认值 | 说明 |
+|---|---|---|
+| `"store_row_column"` | `false` | 对所有列开启行存。 |
+| `"row_store_page_size"` | `16384`(16 KB) | 行存 page 大小(字节)。 |
 
-page 是存储读写的最小单元,page_size 是行存 page 的大小,也就是说读一行也需要产生一个 page 的 IO。这个值越大压缩效果越好存储空间占用越低,但是点查时 IO 开销越大性能越低(因为一次 IO 至少读一个 page),反过来值越小存储空间越高,点查性能越好。默认值 16KB 是大多数情况下比较均衡的选择,如果更偏向查询性能可以配置较小的值比如 4KB 甚至更低,如果更偏向存储空间可以配置较大的值比如 64KB 甚至更高。
+`page` 是存储读写的最小单元,`page_size` 是行存 page 的大小,也就是说读一行也需要产生一个 page 的 IO。这个值越大压缩效果越好存储空间占用越低,但是点查时 IO 开销越大性能越低(因为一次 IO 至少读一个 page),反过来值越小存储空间越高,点查性能越好。默认值 16KB 是大多数情况下比较均衡的选择,如果更偏向查询性能可以配置较小的值比如 4KB 甚至更低,如果更偏向存储空间可以配置较大的值比如 64KB 甚至更高。
 
+:::note
+2.1 版本不支持通过 `row_store_columns` 属性指定部分列开启行存。
+:::
 
 ## 使用示例
 
-下面的例子创建一个 8 列的表,为了高并发点查性能配置 page_size 为 4KB。
+下面的例子创建一个 8 列的表,为了高并发点查性能配置 `row_store_page_size` 为 4KB。
 
-```
+```sql
 CREATE TABLE `tbl_point_query` (
     `key` int(11) NULL,
     `v1` decimal(27, 9) NULL,
@@ -57,9 +55,10 @@ PROPERTIES (
 );
 ```
 
-查询
-```
-SELECT key, v1, v3, v5, v7 FROM tbl_point_query WHERE key = 100;
+查询:
+
+```sql
+SELECT key, v1, v3, v5, v7 FROM tbl_point_query WHERE key = 100;
 ```
 
 更多点查的使用请参考 [高并发点查](../query-acceleration/high-concurrent-point-query) 。
@@ -68,4 +67,5 @@ SELECT key, v1, v3, v5, v7 FROM tbl_point_query WHERE key = 100;
 ## 注意事项
 
 1. 开启行存后占用的存储空间会增加,存储空间的增加和数据特点有关,一般是原来表的 2 到 10 倍,具体空间占用需要使用实际数据测试。
-2. 行存的 page_size 对存储空间的也有影响,可以根据前面的表属性参数 `row_store_page_size` 说明进行调整。
+2. 行存的 `page_size` 对存储空间的也有影响,可以根据前面的表属性参数 `row_store_page_size` 说明进行调整。
+3. 不支持通过 `ALTER TABLE` 修改 `store_row_column` 属性。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.x/table-design/row-store.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.x/table-design/row-store.md
index 19c45581918..9a9a7b154ac 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.x/table-design/row-store.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.x/table-design/row-store.md
@@ -2,52 +2,88 @@
 {
     "title": "行列混存",
     "language": "zh-CN",
-    "description": "Doris 默认采用列式存储,每个列连续存储,在分析场景(如聚合,过滤,排序等)有很好的性能,因为只需要读取所需要的列减少不必要的 IO。但是在点查场景(比如 SELECT ),需要读取所有列,每个列都需要一次 IO 导致 IOPS 成为瓶颈,特别对列多的宽表(比如上百列)尤为明显。"
+    "description": "Doris 行列混存功能在列存基础上增加行存,降低宽表点查场景的 IOPS 开销。"
 }
 ---
 
-## 行列混存介绍
+## 概述
 
-Doris 默认采用列式存储,每个列连续存储,在分析场景(如聚合,过滤,排序等)有很好的性能,因为只需要读取所需要的列减少不必要的 IO。但是在点查场景(比如 `SELECT *`),需要读取所有列,每个列都需要一次 IO 导致 IOPS 成为瓶颈,特别对列多的宽表(比如上百列)尤为明显。
+Doris 默认采用列式存储,每个列连续存储。列存在分析场景(聚合、过滤、排序等)表现优异,因为只需读取所需的列。但在点查场景(如 `SELECT *`)中需要读取所有列,每列一次 IO,在列数较多的宽表(如上百列)上 IOPS 会成为瓶颈。
 
-为了解决点查场景 IOPS 的瓶颈问题,Doris 2.0.0 版本开始支持行列混存,用户建表时指定开启行存后,点查(比如 `SELECT *`)每一行只需要一次 IO,在宽表列很多的情况下性能有数量级提升。
+为此,Doris 从 2.0.0 版本开始支持**行列混存**。在建表时开启行存后,系统会在存储时增加一个额外的列,将该行所有列拼接为紧凑二进制格式存储。点查时只需一次 IO 即可读取完整行数据,大幅降低 IOPS、提升查询延迟。
 
-行存的原理是在存储时增加了一个额外的列,这个列将对应行的所有列拼接起来采用特殊的二进制格式存储。
+## 适用场景
 
-## 使用语法
+以下场景推荐开启行存:
 
-建表时在表的 PROPERTIES 中指定是否开启行存,哪些列开启行存,行存的存储压缩单元大小 page_size。
+- **主键高并发点查**:在 Unique Key Merge-On-Write(MOW)表上,根据完整主键查找特定行。
+- **宽表 `SELECT *` 查询**:在 Duplicate 表或 MOW 表上,仅返回少量行的 TOPN 查询。
 
-1. 是否开启行存:默认为 false 不开启
-```
-"store_row_column" = "true"
-```
+如果业务以分析查询为主(聚合、对少数列的复杂过滤等),通常仅列存即可满足需求。
 
-2. 哪些列开启行存:如果 `"store_row_column" = "true"`,默认所有列开启行存,若需要指定部分列开启行存,设置 row_store_columns 参数(3.0 之后的版本),格式为逗号分割的列名
-```
-"row_store_columns" = "column1,column2,column3"
-```
+## 建表配置
 
-3. 行存 page_size:默认为 16KB。
-```
-"row_store_page_size" = "16384"
-```
+通过 `CREATE TABLE` 的 `PROPERTIES` 设置行存相关参数:
+
+| 参数 | 默认值 | 支持版本 | 说明 |
+|------|--------|---------|------|
+| `"store_row_column" = "true"` | `false` | 2.0+ | 对**所有列**开启行存。 |
+| `"row_store_columns" = "col1,col2,..."` | 全部列 | 3.0+ | 仅对**指定列**开启行存。设置此参数时 `store_row_column` 隐式启用。相比全量行存可显著降低存储开销。 |
+| `"row_store_page_size" = "16384"` | `16384`(16 KB) | 2.0+ | 行存 page 大小(字节)。page 是最小 IO 单元——即使只读一行也需产生一个 page 的 IO。 |
 
-page 是存储读写的最小单元,page_size 是行存 page 的大小,也就是说读一行也需要产生一个 page 的 IO。这个值越大压缩效果越好存储空间占用越低,但是点查时 IO 开销越大性能越低(因为一次 IO 至少读一个 page),反过来值越小存储空间越高,点查性能越好。默认值 16KB 是大多数情况下比较均衡的选择,如果更偏向查询性能可以配置较小的值比如 4KB 甚至更低,如果更偏向存储空间可以配置较大的值比如 64KB 甚至更高。
+**`row_store_page_size` 调优建议:**
+
+| 优化目标 | 建议 page_size | 权衡 |
+|---------|---------------|------|
+| 最佳点查性能 | 4096(4 KB)或更小 | 存储开销更高 |
+| 均衡(默认) | 16384(16 KB) | — |
+| 最小存储开销 | 65536(64 KB)或更大 | 点查延迟更高 |
 
 ## 行存命中条件
-行存命中条件分成两种情况,一种是高并发主键点查需要依赖表的属性以及查询满足点查条件,另一种是单表 SELECT * 查询,下面针对这两种查询进行说明。
 
-- 对于主键高并发点查,建表属性需要开启 `"enable_unique_key_merge_on_write" = "true"`(MOW 表)以及 `"store_row_column" = "true"`(所有列都会在行存中单独额外存一份,存储代价相对较高)或者 `"row_store_columns" = "key,v1,v3,v5,v7"`(只会存储询部分列到行存中)。查询的时候注意 where 条件中需要有所有的主键等值并且是 AND,例如`SELECT * FROM tbl WHERE k1 = 1 AND k2 = 2` 或者查询部分列 `SELECT v1, v2 FROM tbl WHERE k1 = 1 AND k2 = 2`,如果行存只包含了部分列(v1),但是查询的列不在行存中(例如 v2),那么将会从列存中查询剩余的列,该例子中 v1 将会从行存查询,而 v2 会从列存中查询(列存的 page size 更大,会有更多的读放大),通过 EXPLAIN 可以确认是否命中主键高并发点查优化,更多点查的使用请参考 [高并发点查](../query- [...]
+行存在以下两种场景中被触发,各有不同的前提条件。
 
+### 场景一:主键高并发点查(Short-Circuit)
 
-- 对于一般的非主键点查,如果想要走行存那么表模型 DUPLICATE 或者开启`"enable_unique_key_merge_on_write" = "true"`(MOW 表),以及及 `"store_row_column" = "true"`(所有列都会在行存中单独额外存一份,存储代价相对较高)。查询满足这种模式将可以命中行存`SELECT * FROM tble [WHERE XXXXX] ORDER BY XXX LIMIT N` 方括号中的是可选查询条件,注意目前只能是`SELECT *`,且需要命中 TOPN 的延迟物化优化,具体参考[TOPN 查询优化](../query-acceleration/optimization-technology-principle/topn-optimization),即命中`OPT TWO PHASE`。最后通过 EXPLAIN 查看是否有有`FETCH ROW STORE`相应的标记即可确认命中行存
+需要**同时满足**以下所有条件:
 
-## 使用示例
+1. 表为 **Unique Key MOW 表**(`"enable_unique_key_merge_on_write" = "true"`)。
+2. 已通过 `"store_row_column" = "true"` 或 `"row_store_columns" = "..."` 开启行存。
+3. `WHERE` 子句包含**所有主键列的等值条件**,用 `AND` 连接。
 
-下面的例子创建一个 8 列的表,其中 "key,v1,v3,v5,v7" 这 5 列开启行存,为了高并发点查性能配置 page_size 为 4KB。
+查询示例:
 
+```sql
+-- 查询全部列
+SELECT * FROM tbl WHERE k1 = 1 AND k2 = 2;
+
+-- 查询部分列
+SELECT v1, v2 FROM tbl WHERE k1 = 1 AND k2 = 2;
 ```
+
+**部分列行存的处理:** 如果行存只包含部分列(如 `v1`),但查询还请求了不在行存中的列(如 `v2`),Doris 会从列存中读取缺失的列。行存中的列仍然高效读取,其余列执行正常的列存 IO。
+
+**验证方法:** 对查询执行 `EXPLAIN`,检查输出中是否包含 `SHORT-CIRCUIT` 标记。详见 [高并发点查](../query-acceleration/high-concurrent-point-query)。
+
+### 场景二:TOPN 延迟物化查询(Fetch Row Store)
+
+需要**同时满足**以下所有条件:
+
+1. 表为 **Duplicate 表**或 **Unique Key MOW 表**(`"enable_unique_key_merge_on_write" = "true"`)。
+2. 必须对**所有列**开启行存(`"store_row_column" = "true"`)。
+3. 查询满足 `SELECT * FROM tbl [WHERE ...] ORDER BY ... LIMIT N` 模式。
+4. 必须是 `SELECT *`——不支持选择特定列。
+5. 需要命中 TOPN 延迟物化优化。详见 [TOPN 查询优化](../query-acceleration/optimization-technology-principle/topn-optimization)。
+
+**验证方法:** 对查询执行 `EXPLAIN`,检查输出中是否同时包含 `FETCH ROW STORE` 和 `OPT TWO PHASE` 标记。
+
+## 使用示例
+
+### 示例一:Unique Key MOW 表 + 部分列行存
+
+创建一个 8 列的表,对其中 5 列开启行存,设置 `page_size` 为 4 KB 以获得最佳点查性能:
+
+```sql
 CREATE TABLE `tbl_point_query` (
     `k` int(11) NULL,
     `v1` decimal(27, 9) NULL,
@@ -69,16 +105,19 @@ PROPERTIES (
 );
 ```
 
-查询 1
+执行点查:
 
+```sql
+SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100;
 ```
-SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100
-```
-explain 上述语句应该包含 `SHORT-CIRCUIT` 相应的标记。更多点查的使用请参考 [高并发点查](../query-acceleration/high-concurrent-point-query) 。
 
-下面这个例子展示了 DUPLICATE 表怎么命中行存查询条件
+对该语句执行 `EXPLAIN`,输出中应包含 `SHORT-CIRCUIT` 标记。更多用法详见 [高并发点查](../query-acceleration/high-concurrent-point-query)。
 
-```
+### 示例二:Duplicate 表 + 全量行存
+
+创建一个 Duplicate 表,对所有列开启行存:
+
+```sql
 CREATE TABLE `tbl_duplicate` (
     `k` int(11) NULL,
     `v1` string NULL
@@ -92,16 +131,21 @@ PROPERTIES (
     "row_store_page_size" = "4096"
 );
 ```
-` "store_row_column" = "true",` 是必须的
 
-查询 2(注意命中 TOPN 查询优化以及需要是`SELECT *`)
+:::note
+Duplicate 表必须设置 `"store_row_column" = "true"`,不支持 `row_store_columns` 指定部分列——所有列均会存入行存。
+:::
 
+执行 TOPN 查询:
+
+```sql
+SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10;
 ```
-SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10
-```
-explain 上述语句应该包含`FETCH ROW STORE` 相应的标记,以及`OPT TWO PHASE`标记
+
+对该语句执行 `EXPLAIN`,输出中应同时包含 `FETCH ROW STORE` 标记和 `OPT TWO PHASE` 标记。
 
 ## 注意事项
 
-1. 开启行存后占用的存储空间会增加,存储空间的增加和数据特点有关,一般是原来表的 2 到 10 倍,具体空间占用需要使用实际数据测试。
-2. 行存的 page_size 对存储空间的也有影响,可以根据前面的表属性参数 `row_store_page_size` 说明进行调整。
+1. **存储开销:** 开启行存会增加磁盘使用量。根据数据特点,额外存储通常为原表大小的 2–10 倍。建议使用实际数据测试以评估影响。
+2. **page_size 影响存储:** 较小的 `row_store_page_size` 可提升点查性能,但会增加存储开销。调优建议详见[建表配置](#建表配置)章节。
+3. **不支持 ALTER:** 不支持通过 `ALTER TABLE` 修改 `store_row_column` 和 `row_store_columns` 属性。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/table-design/row-store.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/table-design/row-store.md
index deda707aad0..9a9a7b154ac 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/table-design/row-store.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/table-design/row-store.md
@@ -2,52 +2,88 @@
 {
     "title": "行列混存",
     "language": "zh-CN",
-    "description": "Doris 默认采用列式存储,每个列连续存储,在分析场景(如聚合,过滤,排序等)有很好的性能,因为只需要读取所需要的列减少不必要的 IO。但是在点查场景(比如 SELECT ),需要读取所有列,每个列都需要一次 IO 导致 IOPS 成为瓶颈,特别对列多的宽表(比如上百列)尤为明显。"
+    "description": "Doris 行列混存功能在列存基础上增加行存,降低宽表点查场景的 IOPS 开销。"
 }
 ---
 
-## 行列混存介绍
+## 概述
 
-Doris 默认采用列式存储,每个列连续存储,在分析场景(如聚合,过滤,排序等)有很好的性能,因为只需要读取所需要的列减少不必要的 IO。但是在点查场景(比如 `SELECT *`),需要读取所有列,每个列都需要一次 IO 导致 IOPS 成为瓶颈,特别对列多的宽表(比如上百列)尤为明显。
+Doris 默认采用列式存储,每个列连续存储。列存在分析场景(聚合、过滤、排序等)表现优异,因为只需读取所需的列。但在点查场景(如 `SELECT *`)中需要读取所有列,每列一次 IO,在列数较多的宽表(如上百列)上 IOPS 会成为瓶颈。
 
-为了解决点查场景 IOPS 的瓶颈问题,Doris 2.0.0 版本开始支持行列混存,用户建表时指定开启行存后,点查(比如 `SELECT *`)每一行只需要一次 IO,在宽表列很多的情况下性能有数量级提升。
+为此,Doris 从 2.0.0 版本开始支持**行列混存**。在建表时开启行存后,系统会在存储时增加一个额外的列,将该行所有列拼接为紧凑二进制格式存储。点查时只需一次 IO 即可读取完整行数据,大幅降低 IOPS、提升查询延迟。
 
-行存的原理是在存储时增加了一个额外的列,这个列将对应行的所有列拼接起来采用特殊的二进制格式存储。
+## 适用场景
 
-## 使用语法
+以下场景推荐开启行存:
 
-建表时在表的 PROPERTIES 中指定是否开启行存,哪些列开启行存,行存的存储压缩单元大小 page_size。
+- **主键高并发点查**:在 Unique Key Merge-On-Write(MOW)表上,根据完整主键查找特定行。
+- **宽表 `SELECT *` 查询**:在 Duplicate 表或 MOW 表上,仅返回少量行的 TOPN 查询。
 
-1. 是否开启行存:默认为 false 不开启
-```
-"store_row_column" = "true"
-```
+如果业务以分析查询为主(聚合、对少数列的复杂过滤等),通常仅列存即可满足需求。
 
-2. 哪些列开启行存:如果 `"store_row_column" = "true"`,默认所有列开启行存,若需要指定部分列开启行存,设置 row_store_columns 参数(3.0 之后的版本),格式为逗号分割的列名
-```
-"row_store_columns" = "column1,column2,column3"
-```
+## 建表配置
 
-3. 行存 page_size:默认为 16KB。
-```
-"row_store_page_size" = "16384"
-```
+通过 `CREATE TABLE` 的 `PROPERTIES` 设置行存相关参数:
+
+| 参数 | 默认值 | 支持版本 | 说明 |
+|------|--------|---------|------|
+| `"store_row_column" = "true"` | `false` | 2.0+ | 对**所有列**开启行存。 |
+| `"row_store_columns" = "col1,col2,..."` | 全部列 | 3.0+ | 仅对**指定列**开启行存。设置此参数时 `store_row_column` 隐式启用。相比全量行存可显著降低存储开销。 |
+| `"row_store_page_size" = "16384"` | `16384`(16 KB) | 2.0+ | 行存 page 大小(字节)。page 是最小 IO 单元——即使只读一行也需产生一个 page 的 IO。 |
 
-page 是存储读写的最小单元,page_size 是行存 page 的大小,也就是说读一行也需要产生一个 page 的 IO。这个值越大压缩效果越好存储空间占用越低,但是点查时 IO 开销越大性能越低(因为一次 IO 至少读一个 page),反过来值越小存储空间越高,点查性能越好。默认值 16KB 是大多数情况下比较均衡的选择,如果更偏向查询性能可以配置较小的值比如 4KB 甚至更低,如果更偏向存储空间可以配置较大的值比如 64KB 甚至更高。
+**`row_store_page_size` 调优建议:**
+
+| 优化目标 | 建议 page_size | 权衡 |
+|---------|---------------|------|
+| 最佳点查性能 | 4096(4 KB)或更小 | 存储开销更高 |
+| 均衡(默认) | 16384(16 KB) | — |
+| 最小存储开销 | 65536(64 KB)或更大 | 点查延迟更高 |
 
 ## 行存命中条件
-行存命中条件分成两种情况,一种是高并发主键点查需要依赖表的属性以及查询满足点查条件,另一种是单表 SELECT * 查询,下面针对这两种查询进行说明。
 
-- 对于主键高并发点查,建表属性需要开启 `"enable_unique_key_merge_on_write" = "true"`(MOW 表)以及 `"store_row_column" = "true"`(所有列都会在行存中单独额外存一份,存储代价相对较高)或者 `"row_store_columns" = "key,v1,v3,v5,v7"`(只会存储询部分列到行存中)。查询的时候注意 where 条件中需要有所有的主键等值并且是 AND,例如`SELECT * FROM tbl WHERE k1 = 1 AND k2 = 2` 或者查询部分列 `SELECT v1, v2 FROM tbl WHERE k1 = 1 AND k2 = 2`,如果行存只包含了部分列(v1),但是查询的列不在行存中(例如 v2),那么将会从列存中查询剩余的列,该例子中 v1 将会从行存查询,而 v2 会从列存中查询(列存的 page size 更大,会有更多的读放大),通过 EXPLAIN 可以确认是否命中主键高并发点查优化,更多点查的使用请参考 [高并发点查](../query- [...]
+行存在以下两种场景中被触发,各有不同的前提条件。
 
+### 场景一:主键高并发点查(Short-Circuit)
 
-- 对于一般的非主键点查,如果想要走行存那么表模型 DUPLICATE 或者开启`"enable_unique_key_merge_on_write" = "true"`(MOW 表),以及及 `"store_row_column" = "true"`(所有列都会在行存中单独额外存一份,存储代价相对较高)。查询满足这种模式将可以命中行存`SELECT * FROM tble [WHERE XXXXX] ORDER BY XXX LIMIT N` 方括号中的是可选查询条件,注意目前只能是`SELECT *`,且需要命中 TOPN 的延迟物化优化,具体参考[TOPN 查询优化](../query-acceleration/optimization-technology-principle/topn-optimization),即命中`OPT TWO PHASE`。最后通过 EXPLAIN 查看是否有有`FETCH ROW STORE`相应的标记即可确认命中行存
+需要**同时满足**以下所有条件:
 
-## 使用示例
+1. 表为 **Unique Key MOW 表**(`"enable_unique_key_merge_on_write" = "true"`)。
+2. 已通过 `"store_row_column" = "true"` 或 `"row_store_columns" = "..."` 开启行存。
+3. `WHERE` 子句包含**所有主键列的等值条件**,用 `AND` 连接。
 
-下面的例子创建一个 8 列的表,其中 "key,v1,v3,v5,v7" 这 5 列开启行存,为了高并发点查性能配置 page_size 为 4KB。
+查询示例:
 
+```sql
+-- 查询全部列
+SELECT * FROM tbl WHERE k1 = 1 AND k2 = 2;
+
+-- 查询部分列
+SELECT v1, v2 FROM tbl WHERE k1 = 1 AND k2 = 2;
 ```
+
+**部分列行存的处理:** 如果行存只包含部分列(如 `v1`),但查询还请求了不在行存中的列(如 `v2`),Doris 会从列存中读取缺失的列。行存中的列仍然高效读取,其余列执行正常的列存 IO。
+
+**验证方法:** 对查询执行 `EXPLAIN`,检查输出中是否包含 `SHORT-CIRCUIT` 标记。详见 [高并发点查](../query-acceleration/high-concurrent-point-query)。
+
+### 场景二:TOPN 延迟物化查询(Fetch Row Store)
+
+需要**同时满足**以下所有条件:
+
+1. 表为 **Duplicate 表**或 **Unique Key MOW 表**(`"enable_unique_key_merge_on_write" = "true"`)。
+2. 必须对**所有列**开启行存(`"store_row_column" = "true"`)。
+3. 查询满足 `SELECT * FROM tbl [WHERE ...] ORDER BY ... LIMIT N` 模式。
+4. 必须是 `SELECT *`——不支持选择特定列。
+5. 需要命中 TOPN 延迟物化优化。详见 [TOPN 查询优化](../query-acceleration/optimization-technology-principle/topn-optimization)。
+
+**验证方法:** 对查询执行 `EXPLAIN`,检查输出中是否同时包含 `FETCH ROW STORE` 和 `OPT TWO PHASE` 标记。
+
+## 使用示例
+
+### 示例一:Unique Key MOW 表 + 部分列行存
+
+创建一个 8 列的表,对其中 5 列开启行存,设置 `page_size` 为 4 KB 以获得最佳点查性能:
+
+```sql
 CREATE TABLE `tbl_point_query` (
     `k` int(11) NULL,
     `v1` decimal(27, 9) NULL,
@@ -69,16 +105,19 @@ PROPERTIES (
 );
 ```
 
-查询 1
+执行点查:
 
+```sql
+SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100;
 ```
-SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100
-```
-explain 上述语句应该包含 `SHORT-CIRCUIT` 相应的标记。更多点查的使用请参考 [高并发点查](../query-acceleration/high-concurrent-point-query) 。
 
-下面这个例子展示了 DUPLICATE 表怎么命中行存查询条件
+对该语句执行 `EXPLAIN`,输出中应包含 `SHORT-CIRCUIT` 标记。更多用法详见 [高并发点查](../query-acceleration/high-concurrent-point-query)。
 
-```
+### 示例二:Duplicate 表 + 全量行存
+
+创建一个 Duplicate 表,对所有列开启行存:
+
+```sql
 CREATE TABLE `tbl_duplicate` (
     `k` int(11) NULL,
     `v1` string NULL
@@ -92,17 +131,21 @@ PROPERTIES (
     "row_store_page_size" = "4096"
 );
 ```
-` "store_row_column" = "true",` 是必须的
 
-查询 2(注意命中 TOPN 查询优化以及需要是`SELECT *`)
+:::note
+Duplicate 表必须设置 `"store_row_column" = "true"`,不支持 `row_store_columns` 指定部分列——所有列均会存入行存。
+:::
 
+执行 TOPN 查询:
+
+```sql
+SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10;
 ```
-SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10
-```
-explain 上述语句应该包含`FETCH ROW STORE` 相应的标记,以及`OPT TWO PHASE`标记
 
+对该语句执行 `EXPLAIN`,输出中应同时包含 `FETCH ROW STORE` 标记和 `OPT TWO PHASE` 标记。
 
 ## 注意事项
 
-1. 开启行存后占用的存储空间会增加,存储空间的增加和数据特点有关,一般是原来表的 2 到 10 倍,具体空间占用需要使用实际数据测试。
-2. 行存的 page_size 对存储空间的也有影响,可以根据前面的表属性参数 `row_store_page_size` 说明进行调整。
+1. **存储开销:** 开启行存会增加磁盘使用量。根据数据特点,额外存储通常为原表大小的 2–10 倍。建议使用实际数据测试以评估影响。
+2. **page_size 影响存储:** 较小的 `row_store_page_size` 可提升点查性能,但会增加存储开销。调优建议详见[建表配置](#建表配置)章节。
+3. **不支持 ALTER:** 不支持通过 `ALTER TABLE` 修改 `store_row_column` 和 `row_store_columns` 属性。
diff --git a/versioned_docs/version-2.0/table-design/row-store.md b/versioned_docs/version-2.0/table-design/row-store.md
index 7ef44187ee9..1f43bbf625a 100644
--- a/versioned_docs/version-2.0/table-design/row-store.md
+++ b/versioned_docs/version-2.0/table-design/row-store.md
@@ -15,16 +15,18 @@ The principle of row storage is that an additional column is added during storag
 
 ## Syntax
 
-When creating a table, specify whether to enable row storage in the table's PROPERTIES.
-``` 
-"store_row_column" = "true"
-```
+When creating a table, specify whether to enable row storage and its page size in the table's `PROPERTIES`.
+
+| Property | Default | Description |
+|---|---|---|
+| `"store_row_column"` | `false` | Enable row storage for all columns. |
+| `"row_store_page_size"` | `16384` (16 KB) | Size of the row-store page in bytes. A smaller value increases storage overhead but yields better point-query performance. |
 
 ## Example
 
 The example below creates an 8-column table with row storage enabled.
 
-``` 
+```sql
 CREATE TABLE `tbl_point_query` (
      `key` int(11) NULL,
      `v1` decimal(27, 9) NULL,
@@ -45,15 +47,16 @@ PROPERTIES (
 );
 ```
 
-Query
-```
+Query:
+
+```sql
 SELECT * FROM tbl_point_query WHERE key = 100;
 ```
 
-For more information on point query usage, please refer to [High-Concurrent Point Query](../query-acceleration/high-concurrent-point-query).
+For more information on point query usage, please refer to [High-Concurrent Point Query](../query/high-concurrent-point-query).
 
 
 ## Notice
 
 1. Enabling row storage will increase the storage space used. The increase in storage space is related to the data characteristics and is generally 2 to 10 times the size of the original table. The exact space usage needs to be tested with actual data.
-2. Alter the `store_row_column` is not supported in 2.0
\ No newline at end of file
+2. Modifying the `store_row_column` property via `ALTER TABLE` is not supported.
\ No newline at end of file
diff --git a/versioned_docs/version-2.1/table-design/row-store.md b/versioned_docs/version-2.1/table-design/row-store.md
index c3ceac0ff7e..d7b771c2f6c 100644
--- a/versioned_docs/version-2.1/table-design/row-store.md
+++ b/versioned_docs/version-2.1/table-design/row-store.md
@@ -16,26 +16,24 @@ The principle of row storage is that an additional column is added during storag
 
 ## Syntax
 
-When creating a table, specify whether to enable row storage, and the storage compression unit size page_size in the table's PROPERTIES.
+When creating a table, specify whether to enable row storage, and the storage compression unit size `page_size` in the table's `PROPERTIES`.
 
-1. Whether to enable row storage: defaults to false (not enabled).
-``` 
-"store_row_column" = "true"
-```
-
-1. Row storage page_size: defaults to 16KB.
-``` 
-"row_store_page_size" = "16384"
-```
+| Property | Default | Description |
+|---|---|---|
+| `"store_row_column"` | `false` | Enable row storage for all columns. |
+| `"row_store_page_size"` | `16384` (16 KB) | Size of the row-store page in bytes. |
 
 A page is the smallest unit for storage read and write operations, and `page_size` refers to the size of a row-store page. This means that reading a single row requires generating a page IO. The larger this value is, the better the compression effect and the lower the storage space usage. However, the IO overhead during point queries increases, resulting in lower performance (because each IO operation reads at least one page). Conversely, the smaller the value, the higher the storage spa [...]
 
+:::note
+Version 2.1 does not support the `row_store_columns` property to specify partial columns for row storage.
+:::
 
 ## Example
 
-The example below creates an 8-column table with row storage enabled. To optimize for high-concurrency point query performance, the page_size is configured to 4KB.
+The example below creates an 8-column table with row storage enabled. To optimize for high-concurrency point query performance, the `row_store_page_size` is configured to 4KB.
 
-``` 
+```sql
 CREATE TABLE `tbl_point_query` (
      `key` int(11) NULL,
      `v1` decimal(27, 9) NULL,
@@ -57,8 +55,9 @@ PROPERTIES (
 );
 ```
 
-Query
-```
+Query:
+
+```sql
 SELECT * FROM tbl_point_query WHERE key = 100;
 ```
 
@@ -68,5 +67,5 @@ For more information on point query usage, please refer to [High-Concurrent Poin
 ## Notice
 
 1. Enabling row storage will increase the storage space used. The increase in storage space is related to the data characteristics and is generally 2 to 10 times the size of the original table. The exact space usage needs to be tested with actual data.
-2. The `page_size` of row storage also affects the storage space. You can adjust it based on the previous table attribute parameter `row_store_page_size`.
-3. Alter the `store_row_column` is not supported in 2.1
+2. The `page_size` of row storage also affects the storage space. You can adjust it based on the table attribute parameter `row_store_page_size`.
+3. Modifying the `store_row_column` property via `ALTER TABLE` is not supported.
diff --git a/versioned_docs/version-3.x/table-design/row-store.md b/versioned_docs/version-3.x/table-design/row-store.md
index 9a7bac12314..809c84e8e90 100644
--- a/versioned_docs/version-3.x/table-design/row-store.md
+++ b/versioned_docs/version-3.x/table-design/row-store.md
@@ -2,53 +2,88 @@
 {
     "title": "Hybrid Row-Columnar Storage",
     "language": "en",
-    "description": "Doris uses columnar storage by default, with each column stored contiguously."
+    "description": "Doris hybrid row-columnar storage enables row-oriented storage alongside columnar storage, reducing IOPS for point queries on wide tables."
 }
 ---
 
-## Hybrid Row-Columnar Storage
+## Overview
 
-Doris uses columnar storage by default, with each column stored contiguously. Columnar storage offers excellent performance for analytical scenarios (such as aggregation, filtering, sorting, etc.), as it only reads the necessary columns, reducing unnecessary IO. However, in point query scenarios (such as `SELECT *`), all columns need to be read, requiring an IO operation for each column, which can lead to IOPS becoming a bottleneck, especially for wide tables with many columns (e.g., hun [...]
+Doris uses columnar storage by default, where each column is stored contiguously. Columnar storage performs well in analytical scenarios (aggregation, filtering, sorting, etc.) because it reads only the required columns. However, when a query needs all columns — such as `SELECT *` in point query scenarios — each column requires a separate IO operation, making IOPS a bottleneck. This is especially noticeable on wide tables with hundreds of columns.
 
-To address the IOPS bottleneck in point query scenarios, starting from version 2.0.0, Doris supports Hybrid Row-Columnar Storage. When users create tables, they can specify whether to enable row storage. With row storage enabled, each row only requires one IO operation for point queries (such as `SELECT *`), significantly improving performance.
+To solve this, Doris supports **Hybrid Row-Columnar Storage** since version 2.0.0. When row storage is enabled at table creation, all columns of a row are concatenated into a single additional column using a compact binary format. A point query then reads a complete row in one IO operation instead of one IO per column, significantly reducing IOPS and improving latency.
 
-The principle of row storage is that an additional column is added during storage. This column concatenates all the columns of the corresponding row and stores them using a special binary format.
+## Use Cases
 
-## Syntax
+Row storage is recommended in the following scenarios:
 
-When creating a table, specify whether to enable row storage, which columns to enable row storage for, and the storage compression unit size page_size in the table's PROPERTIES.
+- **High-concurrency primary key point queries** on Unique Key merge-on-write (MOW) tables, where each query looks up a specific row by the full primary key.
+- **Wide-table `SELECT *` queries** on Duplicate or MOW tables where only a small number of rows are returned (TOPN pattern).
 
-1. Whether to enable row storage: defaults to false (not enabled).
-``` 
-"store_row_column" = "true"
-```
+If your workload is primarily analytical (aggregation, complex filtering on a few columns), columnar storage alone is usually sufficient.
 
-2. Which columns to enable row storage for:if `"store_row_column" = "true"`, all columns are enabled by default. If you need to specify that only some columns are enabled for row storage, set the row_store_columns parameter (afer version 3.0), formatted as a comma-separated list of column names.
-``` 
-"row_store_columns" = "column1,column2,column3"
-```
+## Table Properties
 
-3. Row storage page_size: defaults to 16KB.
-``` 
-"row_store_page_size" = "16384"
-```
+Enable and configure row storage through the following `PROPERTIES` when creating a table.
+
+| Property | Default | Since | Description |
+|----------|---------|-------|-------------|
+| `"store_row_column" = "true"` | `false` | 2.0 | Enable row storage for **all** columns. |
+| `"row_store_columns" = "col1,col2,..."` | All columns | 3.0 | Enable row storage for **specified columns only**. When this property is set, `store_row_column` is implicitly enabled. Using selective columns reduces storage overhead compared to storing all columns. |
+| `"row_store_page_size" = "16384"` | `16384` (16 KB) | 2.0 | Size of the row-store page in bytes. A page is the minimum IO unit — reading even a single row requires one page IO. |
+
+**Tuning `row_store_page_size`:**
 
-A page is the smallest unit for storage read and write operations, and `page_size` refers to the size of a row-store page. This means that reading a single row requires generating a page IO. The larger this value is, the better the compression effect and the lower the storage space usage. However, the IO overhead during point queries increases, resulting in lower performance (because each IO operation reads at least one page). Conversely, the smaller the value, the higher the storage spa [...]
+| Goal | Recommended page_size | Trade-off |
+|------|----------------------|-----------|
+| Best point query performance | 4096 (4 KB) or smaller | Higher storage overhead |
+| Balanced (default) | 16384 (16 KB) | — |
+| Minimum storage overhead | 65536 (64 KB) or larger | Higher point query latency |
 
-## Row Store Hit Conditions
+## When Row Storage Is Used
 
-Row store hit conditions are divided into two scenarios: one is high-concurrency primary key point queries that depend on table attributes and satisfy point query conditions, and the other is single-table `SELECT *` queries. These two query types are explained below.
+Row storage is triggered in two scenarios. Each has different prerequisites.
 
-- For high-concurrency primary key point queries, the table attributes need to have `"enable_unique_key_merge_on_write" = "true"` (MOW table) and `"store_row_column" = "true"` (all columns are stored separately in the row store, which incurs relatively high storage costs) or `"row_store_columns" = "key,v1,v3,v5,v7"` (only specified columns are stored in the row store). When querying, ensure the `WHERE` clause includes all primary keys with equality conditions connected by `AND`, e.g., `S [...]
+### Scenario 1: High-Concurrency Primary Key Point Query (Short-Circuit)
 
-- For general non-primary key point queries, to utilize the row store, the table model must be `DUPLICATE` or have `"enable_unique_key_merge_on_write" = "true"` (MOW table) and `"store_row_column" = "true"` (all columns are stored separately in the row store, which incurs relatively high storage costs). Queries satisfying this pattern can hit the row store with `SELECT * FROM tbl [WHERE XXXXX] ORDER BY XXX LIMIT N`, where the content in square brackets is an optional query condition. Not [...]
+This optimization applies when **all** of the following conditions are met:
 
+1. The table is a **Unique Key MOW table** (`"enable_unique_key_merge_on_write" = "true"`).
+2. Row storage is enabled via `"store_row_column" = "true"` or `"row_store_columns" = "..."`.
+3. The `WHERE` clause contains **equality conditions on all primary key columns**, joined by `AND`.
 
-## Usage Examples
+Example queries:
 
-The following example creates a table with 8 columns, where the 5 columns `key, v1, v3, v5, v7` are enabled for row store, and the `page_size` is set to 4KB for high-concurrency point query performance.
+```sql
+-- Full row retrieval
+SELECT * FROM tbl WHERE k1 = 1 AND k2 = 2;
 
+-- Partial column retrieval
+SELECT v1, v2 FROM tbl WHERE k1 = 1 AND k2 = 2;
 ```
+
+**Partial column coverage:** If the row store contains only some columns (e.g., `v1`) but the query also requests columns not in the row store (e.g., `v2`), Doris fetches the missing columns from the column store. The columns in the row store are still read efficiently, while the remaining columns incur normal columnar IO.
+
+**Verification:** Run `EXPLAIN` on the query and check for the `SHORT-CIRCUIT` marker. For details, see [High-Concurrency Point Query](../query-acceleration/high-concurrent-point-query).
+
+### Scenario 2: TOPN Deferred Materialization Query (Fetch Row Store)
+
+This optimization applies when **all** of the following conditions are met:
+
+1. The table is a **Duplicate** table, or a **Unique Key MOW table** (`"enable_unique_key_merge_on_write" = "true"`).
+2. **All columns** must be in the row store (`"store_row_column" = "true"`).
+3. The query follows the pattern `SELECT * FROM tbl [WHERE ...] ORDER BY ... LIMIT N`.
+4. The query must be `SELECT *` — selecting specific columns is not supported for this optimization.
+5. The TOPN deferred materialization optimization must be triggered. For details, see [TOPN Query Optimization](../query-acceleration/optimization-technology-principle/topn-optimization).
+
+**Verification:** Run `EXPLAIN` on the query and check for both the `FETCH ROW STORE` and `OPT TWO PHASE` markers.
+
+## Examples
+
+### Example 1: Unique Key MOW Table with Selective Row Store Columns
+
+Create a table with 8 columns, enable row storage for 5 selected columns, and set `page_size` to 4 KB for optimal point query performance:
+
+```sql
 CREATE TABLE `tbl_point_query` (
     `k` int(11) NULL,
     `v1` decimal(27, 9) NULL,
@@ -70,19 +105,22 @@ PROPERTIES (
 );
 ```
 
-Query 1
+Point query on the row-stored columns:
 
+```sql
+SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100;
 ```
-SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100
-```
-The `EXPLAIN` output for the above statement should include the `SHORT-CIRCUIT` marker. For more details on point query usage, refer to [High-Concurrency Point Query](../query-acceleration/high-concurrent-point-query).
 
-The following example demonstrates how a `DUPLICATE` table can meet row store query conditions.
+Run `EXPLAIN` on this query — the output should include the `SHORT-CIRCUIT` marker. For more details, see [High-Concurrency Point Query](../query-acceleration/high-concurrent-point-query).
 
-```
+### Example 2: Duplicate Table with Full Row Store
+
+Create a Duplicate table with row storage enabled for all columns:
+
+```sql
 CREATE TABLE `tbl_duplicate` (
     `k` int(11) NULL,
-    `v1` string NULw
+    `v1` string NULL
 ) ENGINE=OLAP
 DUPLICATE KEY(`k`)
 COMMENT 'OLAP'
@@ -94,17 +132,20 @@ PROPERTIES (
 );
 ```
 
-`"store_row_column" = "true"` is required.
+:::note
+`"store_row_column" = "true"` is required for Duplicate tables. The `row_store_columns` property is not supported with Duplicate tables — all columns are stored in the row store.
+:::
 
-Query 2 (Note: It must hit TOPN query optimization and must be `SELECT *`)
+TOPN query using row storage:
 
-```
-SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10
+```sql
+SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10;
 ```
 
-The `EXPLAIN` output for the above statement should include the `FETCH ROW STORE` marker and the `OPT TWO PHASE` marker.
+Run `EXPLAIN` on this query — the output should include both the `FETCH ROW STORE` marker and the `OPT TWO PHASE` marker.
 
-## Notice
+## Limitations
 
-1. Enabling row storage will increase the storage space used. The increase in storage space is related to the data characteristics and is generally 2 to 10 times the size of the original table. The exact space usage needs to be tested with actual data.
-2. The `page_size` of row storage also affects the storage space. You can adjust it based on the previous table attribute parameter `row_store_page_size`.
+1. **Storage overhead:** Enabling row storage increases disk usage. Depending on data characteristics, the additional storage is typically 2–10× the original table size. Test with actual data to measure the impact.
+2. **page_size affects storage:** A smaller `row_store_page_size` improves point query performance but increases storage overhead. See the [Table Properties](#table-properties) section for tuning guidance.
+3. **ALTER not supported:** Modifying the `store_row_column` and `row_store_columns` properties via `ALTER TABLE` is not supported.
diff --git a/versioned_docs/version-4.x/table-design/row-store.md b/versioned_docs/version-4.x/table-design/row-store.md
index 85a81d92859..809c84e8e90 100644
--- a/versioned_docs/version-4.x/table-design/row-store.md
+++ b/versioned_docs/version-4.x/table-design/row-store.md
@@ -2,54 +2,88 @@
 {
     "title": "Hybrid Row-Columnar Storage",
     "language": "en",
-    "description": "Doris uses columnar storage by default, with each column stored contiguously."
+    "description": "Doris hybrid row-columnar storage enables row-oriented storage alongside columnar storage, reducing IOPS for point queries on wide tables."
 }
 ---
 
-## Hybrid Row-Columnar Storage
+## Overview
 
-Doris uses columnar storage by default, with each column stored contiguously. Columnar storage offers excellent performance for analytical scenarios (such as aggregation, filtering, sorting, etc.), as it only reads the necessary columns, reducing unnecessary IO. However, in point query scenarios (such as `SELECT *`), all columns need to be read, requiring an IO operation for each column, which can lead to IOPS becoming a bottleneck, especially for wide tables with many columns (e.g., hun [...]
+Doris uses columnar storage by default, where each column is stored contiguously. Columnar storage performs well in analytical scenarios (aggregation, filtering, sorting, etc.) because it reads only the required columns. However, when a query needs all columns — such as `SELECT *` in point query scenarios — each column requires a separate IO operation, making IOPS a bottleneck. This is especially noticeable on wide tables with hundreds of columns.
 
-To address the IOPS bottleneck in point query scenarios, starting from version 2.0.0, Doris supports Hybrid Row-Columnar Storage. When users create tables, they can specify whether to enable row storage. With row storage enabled, each row only requires one IO operation for point queries (such as `SELECT *`), significantly improving performance.
+To solve this, Doris supports **Hybrid Row-Columnar Storage** since version 2.0.0. When row storage is enabled at table creation, all columns of a row are concatenated into a single additional column using a compact binary format. A point query then reads a complete row in one IO operation instead of one IO per column, significantly reducing IOPS and improving latency.
 
-The principle of row storage is that an additional column is added during storage. This column concatenates all the columns of the corresponding row and stores them using a special binary format.
+## Use Cases
 
-## Syntax
+Row storage is recommended in the following scenarios:
 
-When creating a table, specify whether to enable row storage, which columns to enable row storage for, and the storage compression unit size page_size in the table's PROPERTIES.
+- **High-concurrency primary key point queries** on Unique Key merge-on-write (MOW) tables, where each query looks up a specific row by the full primary key.
+- **Wide-table `SELECT *` queries** on Duplicate or MOW tables where only a small number of rows are returned (TOPN pattern).
 
-1. Whether to enable row storage: defaults to false (not enabled).
-``` 
-"store_row_column" = "true"
-```
+If your workload is primarily analytical (aggregation, complex filtering on a few columns), columnar storage alone is usually sufficient.
 
-2. Which columns to enable row storage for:if `"store_row_column" = "true"`, all columns are enabled by default. If you need to specify that only some columns are enabled for row storage, set the row_store_columns parameter (afer version 3.0), formatted as a comma-separated list of column names.
-``` 
-"row_store_columns" = "column1,column2,column3"
-```
+## Table Properties
 
-3. Row storage page_size: defaults to 16KB.
-``` 
-"row_store_page_size" = "16384"
-```
+Enable and configure row storage through the following `PROPERTIES` when creating a table.
 
-A page is the smallest unit for storage read and write operations, and `page_size` refers to the size of a row-store page. This means that reading a single row requires generating a page IO. The larger this value is, the better the compression effect and the lower the storage space usage. However, the IO overhead during point queries increases, resulting in lower performance (because each IO operation reads at least one page). Conversely, the smaller the value, the higher the storage spa [...]
+| Property | Default | Since | Description |
+|----------|---------|-------|-------------|
+| `"store_row_column" = "true"` | `false` | 2.0 | Enable row storage for **all** columns. |
+| `"row_store_columns" = "col1,col2,..."` | All columns | 3.0 | Enable row storage for **specified columns only**. When this property is set, `store_row_column` is implicitly enabled. Using selective columns reduces storage overhead compared to storing all columns. |
+| `"row_store_page_size" = "16384"` | `16384` (16 KB) | 2.0 | Size of the row-store page in bytes. A page is the minimum IO unit — reading even a single row requires one page IO. |
 
+**Tuning `row_store_page_size`:**
 
-## Row Store Hit Conditions
+| Goal | Recommended page_size | Trade-off |
+|------|----------------------|-----------|
+| Best point query performance | 4096 (4 KB) or smaller | Higher storage overhead |
+| Balanced (default) | 16384 (16 KB) | — |
+| Minimum storage overhead | 65536 (64 KB) or larger | Higher point query latency |
 
-Row store hit conditions are divided into two scenarios: one is high-concurrency primary key point queries that depend on table attributes and satisfy point query conditions, and the other is single-table `SELECT *` queries. These two query types are explained below.
+## When Row Storage Is Used
 
-- For high-concurrency primary key point queries, the table attributes need to have `"enable_unique_key_merge_on_write" = "true"` (MOW table) and `"store_row_column" = "true"` (all columns are stored separately in the row store, which incurs relatively high storage costs) or `"row_store_columns" = "key,v1,v3,v5,v7"` (only specified columns are stored in the row store). When querying, ensure the `WHERE` clause includes all primary keys with equality conditions connected by `AND`, e.g., `S [...]
+Row storage is triggered in two scenarios. Each has different prerequisites.
 
-- For general non-primary key point queries, to utilize the row store, the table model must be `DUPLICATE` or have `"enable_unique_key_merge_on_write" = "true"` (MOW table) and `"store_row_column" = "true"` (all columns are stored separately in the row store, which incurs relatively high storage costs). Queries satisfying this pattern can hit the row store with `SELECT * FROM tbl [WHERE XXXXX] ORDER BY XXX LIMIT N`, where the content in square brackets is an optional query condition. Not [...]
+### Scenario 1: High-Concurrency Primary Key Point Query (Short-Circuit)
 
+This optimization applies when **all** of the following conditions are met:
 
-## Usage Examples
+1. The table is a **Unique Key MOW table** (`"enable_unique_key_merge_on_write" = "true"`).
+2. Row storage is enabled via `"store_row_column" = "true"` or `"row_store_columns" = "..."`.
+3. The `WHERE` clause contains **equality conditions on all primary key columns**, joined by `AND`.
 
-The following example creates a table with 8 columns, where the 5 columns `key, v1, v3, v5, v7` are enabled for row store, and the `page_size` is set to 4KB for high-concurrency point query performance.
+Example queries:
 
+```sql
+-- Full row retrieval
+SELECT * FROM tbl WHERE k1 = 1 AND k2 = 2;
+
+-- Partial column retrieval
+SELECT v1, v2 FROM tbl WHERE k1 = 1 AND k2 = 2;
 ```
+
+**Partial column coverage:** If the row store contains only some columns (e.g., `v1`) but the query also requests columns not in the row store (e.g., `v2`), Doris fetches the missing columns from the column store. The columns in the row store are still read efficiently, while the remaining columns incur normal columnar IO.
+
+**Verification:** Run `EXPLAIN` on the query and check for the `SHORT-CIRCUIT` marker. For details, see [High-Concurrency Point Query](../query-acceleration/high-concurrent-point-query).
+
+### Scenario 2: TOPN Deferred Materialization Query (Fetch Row Store)
+
+This optimization applies when **all** of the following conditions are met:
+
+1. The table is a **Duplicate** table, or a **Unique Key MOW table** (`"enable_unique_key_merge_on_write" = "true"`).
+2. **All columns** must be in the row store (`"store_row_column" = "true"`).
+3. The query follows the pattern `SELECT * FROM tbl [WHERE ...] ORDER BY ... LIMIT N`.
+4. The query must be `SELECT *` — selecting specific columns is not supported for this optimization.
+5. The TOPN deferred materialization optimization must be triggered. For details, see [TOPN Query Optimization](../query-acceleration/optimization-technology-principle/topn-optimization).
+
+**Verification:** Run `EXPLAIN` on the query and check for both the `FETCH ROW STORE` and `OPT TWO PHASE` markers.
+
+## Examples
+
+### Example 1: Unique Key MOW Table with Selective Row Store Columns
+
+Create a table with 8 columns, enable row storage for 5 selected columns, and set `page_size` to 4 KB for optimal point query performance:
+
+```sql
 CREATE TABLE `tbl_point_query` (
     `k` int(11) NULL,
     `v1` decimal(27, 9) NULL,
@@ -71,19 +105,22 @@ PROPERTIES (
 );
 ```
 
-Query 1
+Point query on the row-stored columns:
 
+```sql
+SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100;
 ```
-SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100
-```
-The `EXPLAIN` output for the above statement should include the `SHORT-CIRCUIT` marker. For more details on point query usage, refer to [High-Concurrency Point Query](../query-acceleration/high-concurrent-point-query).
 
-The following example demonstrates how a `DUPLICATE` table can meet row store query conditions.
+Run `EXPLAIN` on this query — the output should include the `SHORT-CIRCUIT` marker. For more details, see [High-Concurrency Point Query](../query-acceleration/high-concurrent-point-query).
 
-```
+### Example 2: Duplicate Table with Full Row Store
+
+Create a Duplicate table with row storage enabled for all columns:
+
+```sql
 CREATE TABLE `tbl_duplicate` (
     `k` int(11) NULL,
-    `v1` string NULw
+    `v1` string NULL
 ) ENGINE=OLAP
 DUPLICATE KEY(`k`)
 COMMENT 'OLAP'
@@ -95,17 +132,20 @@ PROPERTIES (
 );
 ```
 
-`"store_row_column" = "true"` is required.
+:::note
+`"store_row_column" = "true"` is required for Duplicate tables. The `row_store_columns` property is not supported with Duplicate tables — all columns are stored in the row store.
+:::
 
-Query 2 (Note: It must hit TOPN query optimization and must be `SELECT *`)
+TOPN query using row storage:
 
-```
-SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10
+```sql
+SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10;
 ```
 
-The `EXPLAIN` output for the above statement should include the `FETCH ROW STORE` marker and the `OPT TWO PHASE` marker.
+Run `EXPLAIN` on this query — the output should include both the `FETCH ROW STORE` marker and the `OPT TWO PHASE` marker.
 
-## Notice
+## Limitations
 
-1. Enabling row storage will increase the storage space used. The increase in storage space is related to the data characteristics and is generally 2 to 10 times the size of the original table. The exact space usage needs to be tested with actual data.
-2. The `page_size` of row storage also affects the storage space. You can adjust it based on the previous table attribute parameter `row_store_page_size`.
+1. **Storage overhead:** Enabling row storage increases disk usage. Depending on data characteristics, the additional storage is typically 2–10× the original table size. Test with actual data to measure the impact.
+2. **page_size affects storage:** A smaller `row_store_page_size` improves point query performance but increases storage overhead. See the [Table Properties](#table-properties) section for tuning guidance.
+3. **ALTER not supported:** Modifying the `store_row_column` and `row_store_columns` properties via `ALTER TABLE` is not supported.


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org