# [FAQ] 如何控制 Dumpling 在 SQL 导出时的内存消耗

## Key Words

memory consume, oom, 内存消耗, 内存溢出

## Description

当使用 `--sql <SQL>` 导出指定 SQL 选择出来的记录时，会发现 TiDB Server 消耗内存巨大，如何控制因 Dumpling 导出产生的 TiDB Server 内存消耗。

## Content

1. `tidb_distsql_scan_concurrency` 用来设置请求数据算子的最大并发度，即：每条 SQL 会构造 1 个或多个算子组成执行计划，当算子涉及去 TiKV 取数据时，如：tableReader, indexReader 等，便会参考该变量值作为并发上限读取 Region 数据。因此，在表数据量非常大时，降低导出请求数据算子的并发度上限，是一种可行的方法。
2. `tidb_executor_concurrency` 从 v5.0 版本开始引入，用来统一设置每类（indexlookup、hash join 等）算子的并行度。  
    2.1 当扫描的表**不是**分区表时，即使 `tidb_executor_concurrency = 5`，其**限制的**相关算子并发度只为 1 。  
    2.2 当扫描的表**是**分区表时，在 `static partition prune` 模式下，TiDB 通过 `PartitionUnion` 算子并发处理分区数据，并保证同时运行的**子算子**数量不超过 `tidb_executor_concurrency` 变量值，在 `dynamic partition prune` 模式下，TiDB 会同时并发处理所有分区数据，会给 TiDB 及存储引擎带来压力，其中包含内存占用上升。  

    因此，当导出 SQL 中含有分区表时，建议将分区裁剪模式为 `static`， TiDB 会以 `tidb_executor_concurrency` 为并发执行处理分区查询，配合 `tidb_distsql_scan_concurrency` 降低 TiDB Server 内存消耗，具体变量值大小及内存消耗需 DBA 在实际测试下得出，因为需要在 `导出速度` 及 `内存消耗` 中权衡，且表数据量也不尽相同。  

3. `dumpling --params`，该选项可以在 session 级别配置不同环境变量，原理为当 Dumpling 连接 TiDB 时设置指定系统变量值，以便不干扰全局参数变化。因此，建议在使用 Dumpling 到处数据时，使用该方法改变上述 2 个参数，而不是直接全局修改。  
4. 综上 2 个参数的使用方法如下，例如，导出 test.sbtest1 中所有 id < 100 的记录，并假设 sbtest1 是分区表（如不涉及分区表，可只设置 `tidb_distsql_scan_concurrency`）：  

    ```shell
    tiup dumpling -u root -P 4000 -h 127.0.0.1 -o ./ --filetype csv \
    --sql 'select * from `test`.`sbtest1` where id < 100' \
    --params 'tidb_distsql_scan_concurrency=1,tidb_executor_concurrency=1,tidb_partition_prune_mode=static'
    ```

## Affected Versions

TiDB Version > 5.0
