今天一客户的TiDB数据库环境业务查询报错,单条SQL的执行内存上限,提示如下:
Your query has been cancelled due to exceeding the allowed memory limit for a single SQL query. Please try narrowing your query scope or increase the tidb_mem_quota_query limit and try again
遇到的错误消息表明 SQL 查询超出了 TiDB 中为单个查询设置的内存限制。要解决此问题,您可以采取以下措施:
1. 缩小查询范围
添加条件(WHERE 子句)以限制正在处理的数据量
使用 LIMIT 一次检索更少的行
select 特定列而不是 SELECT *
优化连接:如果您的查询涉及连接,请通过索引连接的列并限制不必要的数据来确保连接效率
-
将查询拆分为更小的部分:如果您正在执行复杂的聚合或处理大型数据集,请尝试将查询拆分为更小、更易于管理的块
2. 增加 tidb_mem_quota_query 限制
要查询当前 TiDB 中 tidb_mem_quota_query 的大小,可以使用以下 SQL 语句:
不过需要注意的是:
SESSION仅对当前会话生效
Global不需要重启 ,TiDB 实例该参数的更改只会影响新的会话或查询,已经在执行中的查询不会受到影响。
如果 TiDB 发生重启,GLOBAL 级别的设置会恢复为默认值
-
在 TiDB 中,如果你想将 tidb_mem_quota_query 参数永久生效,,你可以将该mem-quota-query 参数配置添加到 TiDB 的配置文件中。
3. 使用流式处理获取大量结果
如果您的查询返回大量结果集,请考虑使用流式处理技术以较小的批次检索数据,以减少内存压力。
其他一些TIDB内存参数变量,大部分用户不需要关心。
| Variable Name | Description | Unit | Default Value |
|---|---|---|---|
| tidb_mem_quota_query | Control the memory quota of a query | Byte | 32 << 30 |
| tidb_mem_quota_hashjoin | Control the memory quota of “HashJoinExec” | Byte | 32 << 30 |
| tidb_mem_quota_mergejoin | Control the memory quota of “MergeJoinExec” | Byte | 32 << 30 |
| tidb_mem_quota_sort | Control the memory quota of “SortExec” | Byte | 32 << 30 |
| tidb_mem_quota_topn | Control the memory quota of “TopNExec” | Byte | 32 << 30 |
| tidb_mem_quota_indexlookupreader | Control the memory quota of “IndexLookUpExecutor” | Byte | 32 << 30 |
| tidb_mem_quota_indexlookupjoin | Control the memory quota of “IndexLookUpJoin” | Byte | 32 << 30 |
| tidb_mem_quota_nestedloopapply | Control the memory quota of “NestedLoopApplyExec” | Byte | 32 << 30 |
其它限制SQL的参数 max_execution_time、tidb_retry_limit、tidb_disable_txn_auto_retry、tidb_distsql_scan_concurrency、tidb_index_lookup_size、tidb_index_lookup_concurrency、tidb_index_lookup_join_concurrency、tidb_hash_join_concurrency、tidb_index_serial_scan_concurrency、compatible-kill-query