tidb-server中limit查询问题

如下sql:

SELECT
  data
FROM
  pay_iap_receipt_detail
WHERE
  createTime < '2022-03-30 14:52:52.986'
  AND preOrderFlag IS false
  AND exchangeFlag IS false
LIMIT
  200;
	id                       	task     	estRows	operator info                                                                                                      	actRows	execution info                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     	memory 	disk
	Limit_9                  	root     	200    	offset:0, count:200                                                                                                	200    	time:1.16s, loops:2                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                	N/A    	N/A
	└─IndexLookUp_18         	root     	200    	                                                                                                                   	200    	time:1.16s, loops:1, index_task: {total_time: 1.16s, fetch_handle: 396.9ms, build: 15.2µs, wait: 765.3ms}, table_task: {total_time: 34.6s, num: 9, concurrency: 5}                                                                                                                                                                                                                                                                                                                                                                                	6.34 GB	N/A
	  ├─IndexRangeScan_14    	cop[tikv]	200    	table:pay_iap_receipt_detail, index:idx_create_time(createTime), range:[-inf,2022-03-30 14:52:53), keep order:false	502919 	time:390.3ms, loops:90, cop_task: {num: 1, max: 389.8ms, proc_keys: 502919, tot_proc: 367ms, tot_wait: 1ms, rpc_num: 1, rpc_time: 389.8ms, copr_cache: disabled}, tikv_task:{time:354ms, loops:496}, scan_detail: {total_process_keys: 502919, total_process_keys_size: 23134274, total_keys: 502920, rocksdb: {delete_skipped_count: 0, key_skipped_count: 502919, block: {cache_hit_count: 399, read_count: 0, read_byte: 0 Bytes}}}                                                                                                             	N/A    	N/A
	  └─Limit_17             	cop[tikv]	200    	offset:0, count:200                                                                                                	55770  	time:34.5s, loops:67, cop_task: {num: 679, max: 1.13s, min: 2.08ms, avg: 266.1ms, p95: 767.6ms, max_proc_keys: 224, p95_proc_keys: 224, tot_proc: 31s, tot_wait: 377ms, rpc_num: 679, rpc_time: 3m0.4s, copr_cache: disabled}, tikv_task:{proc max:96ms, min:0s, p80:34ms, p95:53ms, iters:1331, tasks:679}, scan_detail: {total_process_keys: 58507, total_process_keys_size: 6360462489, total_keys: 60278, rocksdb: {delete_skipped_count: 583, key_skipped_count: 5409, block: {cache_hit_count: 439837, read_count: 309, read_byte: 3.82 MB}}}	N/A    	N/A
	    └─Selection_16       	cop[tikv]	200    	isfalse(u7pay.pay_iap_receipt_detail.exchangeflag), isfalse(u7pay.pay_iap_receipt_detail.preorderflag)             	58497  	tikv_task:{proc max:96ms, min:0s, p80:34ms, p95:53ms, iters:1331, tasks:679}                                                                                                                                                                                                                                                                                                                                                                                                                                                                       	N/A    	N/A
	      └─TableRowIDScan_15	cop[tikv]	200    	table:pay_iap_receipt_detail, keep order:false                                                                     	58507  	tikv_task:{proc max:95ms, min:0s, p80:34ms, p95:53ms, iters:1331, tasks:679}                                                                                                                                                                                                                                                                                                                                                                                                                                                                       	N/A    	N/A

看上面执行计划tikv是返回55770 rows给tidb-server,limit没被下推么?还是其它什么问题造成的?

limit 在 tikv 执行的呢

你只用看 task 的类型
root -> tidb
cop[tikv] -> tikv
cop[tiflash] -> tiflash

你可以调整一下 条件 的顺序试试看

看返回的流量就不对,就200条数据,竟然返回6GB的流量

嗯,范围扫 -> proc_keys: 502919

你看这个条件有没有办法在限定一下

查询语句就是这样

调整下条件的顺序看看呢

你的索引 只用到了 create_time 而且 这个表的索引应该也不小,扫一下索引就要6GB, 可以把你的create_time 分时间查下

正常tikv不应该只返回200条数据给tidb么?

estRows 是执行计划预估
actRows 是执行计划实际扫的数

scan_detail: {total_process_keys: 502919
加一下限制条件 在范围扫上,比如给时间字段一个区间

看了你的执行计划;索引是单列索引 index:idx_create_time(createTime)
实际执行的时候要要在这个索引里 找到 你后边的2个条件的记录然后limit。
调优方式
1、对索引字段 缩小范围(使用 预估区间)
2、可以试试索引覆盖。

你的是什么版本?

limit会下推的,请问tidb版本是多少?

我也是

5.3.0

但是我看返回的流量非常的大,有7,8GB左右,然后tidb-server占用的内存也很大有6GB左右;如果tikv只有200行数据返回给tidb,那么不应该有这么大的流量

执行了下这条sql,tidb-server内存从13GB直接减到4GB

区间就是这样,没法改了

有一点就是,在tikv中扫描这么大的量没什么问题,但是只有200行返回给tidb-server,中间网络流量占用了7,8GB,并且tidb-server内存占用6GB,这感觉是不是有问题了?

我的表结构有两个大字段类型(<=0.5MB),但即使是大字段对于只有200行的返回也不应该占用这么多的流量

上面的猜测是基于limit能够下推的情况,如果limit没有下推那么就可以理解为什么会返回这么大的流量

1 个赞
WHERE
  createTime < '2022-03-30 14:52:52.986'
  AND preOrderFlag IS false
  AND exchangeFlag IS false

这样的用法,肯定会查历史的所有数据,在createTime上加索引一点儿用处没有,还不如看下preOrderFlag,exchangeFlag的分布情况,如果90%都不是False,而这个查询又是高频的,可以在这两个字段上加索引。
如果不是为了解决SQL问题,纯粹是为了探究现象的话(而现象确实如此),确实值的讨论

建议贴一下集群分布和监控情况

查询tikv的所有数据没关系,主要是tikv返回给tidb的流量有7,8GB,tidb-server占用的内存高达6GB,这个才是问题

这个就是业务上使用的sql语句,直接把tidb-server查到oom了,就是200条的返回量,多查几次,让tidb-server oom了

每次查询内存就狂飙,就200条的返回量,能让tidb-server内存吃到这么多,也是不明白;在tikv集群间查询所有数据流量大没关系,但是从tikv返回200数据量给tidb-server,不应该会占用这么大的内存

dstat实时抓取tidb-server接收的流量,此tidb-server只运行这条sql语句

1 个赞