求优化建议

【 TiDB 使用环境】

pd * 3 (4c8g)
tidb * 3(4c8g)
tikv * 3(4c8g256g)

【概述】 场景 + 问题概述

    **数据只有23万条.**

   建表语句:

CREATE TABLE group_info (
group_id bigint(20) NOT NULL COMMENT ‘组id’,
parent_group_id bigint(20) NOT NULL COMMENT ‘父组id’,
parent_group_creator_id varchar(100) NOT NULL COMMENT ‘父组的创建id’,
group_title varchar(220) NOT NULL COMMENT ‘组名称’,
group_type tinyint(4) NOT NULL COMMENT ‘组类型’,
group_state tinyint(4) NOT NULL COMMENT ‘组状态’,
start_time datetime NOT NULL COMMENT ‘开始时间’,
end_time datetime NOT NULL COMMENT ‘结束时间’,
group_creator_id varchar(100) NOT NULL COMMENT ‘创建者id’,
referee_id varchar(100) NOT NULL DEFAULT ‘’ COMMENT ‘中介id’,
notice_type tinyint(4) NOT NULL DEFAULT ‘0’ COMMENT ‘通知类型’,
is_delete tinyint(4) DEFAULT ‘0’ COMMENT ‘是否删除’,
create_time datetime NOT NULL COMMENT ‘创建时间’,
update_time datetime NOT NULL COMMENT ‘更新时间’,
create_user varchar(50) NOT NULL COMMENT ‘创建人’,
update_user varchar(50) NOT NULL COMMENT ‘更新人’,
ts timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘时间戳’,
PRIMARY KEY (group_id) /*T![clustered_index] CLUSTERED */,
KEY idx_parent_group_id (parent_group_id) COMMENT ‘父组索引’,
KEY idx_group_creator_id (group_creator_id) COMMENT ‘group_creator_id 索引’,
KEY idx_parent_group_id (parent_group_creator_id) COMMENT ‘父组创建者id索引’
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT=‘组基本信息表’

  查询语句

执行计划sql:select group_id, group_creator_id from group_info where group_creator_id in ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ?) and group_state = 1 and is_delete = 0 order by group_id desc limit 10

压测sql:select group_id, group_creator_id from group_info where group_creator_id in ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ?) and group_state = 1 and start_time < now() and end_time > now() and is_delete = 0 order by group_id desc limit 11

【背景】 做过哪些操作

执行计划:

EXPLAIN_ANALYZE.xlsx (9.8 KB)

【现象】 业务和数据库现象

    压测只能到85QPS,只有一台tikv CPU 保持90%以上,其余六台机器都在15%以下

【问题】 当前遇到的问题

性能比想象中的低太多,求优化建议
一个疑惑点:tikv第二阶段,条件过滤,感觉找够10条即可,为什么要把满足条件的1528全找到?
明白回表数据太多,性能会差,也想确认下,即便是只命中单tikv,会这么差么?
因为正常执行sql,才30ms左右,有性能很好的感觉

(试用新人,不过原理学的多,应该能听懂)

【业务影响】

【TiDB 版本】

5.3

公司集群,没办法执行脚本

1、 tidb前面是否使用了haproxy\lvs这类的负载均衡?
2、show table group_info regions 看看region数量,如果仅一个1tikv 负载高,说明有热点。解决热点方式:
(1)使用pd-ctl operator add split-region xxx 或split table 命令分裂region。region分裂后要跑一段时间等待pd做热点调度 或 pd-ctl operator add transfer-leader xxx xx手动调度leader到空闲tikv
(2)重新设计表结构,tidb解决热点的方式有 : bigint 主键设置为auto_random,非bigint主键设置shard_row_id_bits+pre_split_regions , 使用hash分区。默认建新表后region还在原有tikv,在建表前设置tidb_scatter_region变量 ,region会均衡调度。
3、SQL中有order by 所以需要把所有符合条件的查出来后排序,然后取top 11。执行计划中topN_20是在每个tikv上的排序后取top 11然后返回tidb ,在由tidb排序后取top11(即TopN9)

每个节点压力不均衡, 前端是否有负载均衡配置?
region/region leader 分布是否均衡?

我觉得从这2分方面入手应该能查到问题,具体的处理方法 参考楼上

嗯嗯,好的,非常感谢

嗯嗯,主要是性能比想象中低太多,有些不理解,即便是命中单分片,总感觉也不能只有85的pqs,比较疑惑;

因为在别的表的测试中,48万数据的索引全表扫,也只花了几十ms,85pqs的并发,每次回表数据7000,也不过几十万数据

因为orderby 是PK;我会理解,只需要每个tikv返回10条即可;而且,当前数据,其实还只分布在一个tikv;按一共有3个算,感觉也是最多返回30条;然后,我们的数据命中度来看,也只需要扫描100条左右即可

tidb_enable_paging 有个这个变量 会话级调下在跑跑试试

你好,根据mysql经验,感觉order by + limit 这个点对于sql优化挺重要的,所以还是想请教一下,1528行数据都找到的逻辑,是因为目前还没有实现tikv层考虑order by + limit 么?

从执行计划看 topN_20 是在tikv执行的也就说说 tikv侧取limit 条后返回tikv, tidb的数据存储是以region为单位划分的,每个region是一段连续的空间,tidb的查询会构造coprocessor task,每个region 一个task,然后每个task将结果返回给tidb侧,由于topn 下推到了tikv 所以每个coprocessor task 仅返回tidb需要的limit行数,1528是总的行数,11个cop task(tasks:11) , tidb再将11个 task的limit 10排序后再取最终的limit 10

那是不是可以理解为,Selection_19这一步,是考虑order by + limit 的,理想情况下,找到的条数应该是region数量*limit

是的,看limit 有没有下推tikv

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。