主键查询比mysql慢

【问题描述】:查询速度问题,在mysql中查询,一般不超过1ms,在tidb中查询,时间为7ms(在建立连接的情况下初次查询有时超过30ms)。

【 TiDB 使用环境】生产环境
Tidb:3pd,3kv,3db
Tidb:无写入,
Mysql:单机,无写入
数据记录:520万条记录

【 TiDB 版本】v8.3.0

【 查询语句】:

select * from business_msg where sign_number=‘17747715421’;

【表结构】
表结构:
CREATE TABLE business_msg (
sign_number varchar(20) NOT NULL COMMENT ‘签约号码’,
called_format varchar(50) DEFAULT ‘’ COMMENT ‘被叫号码格式’,
sign_type varchar(50) DEFAULT ‘’ COMMENT ‘签约类型’,
record_flag varchar(50) DEFAULT ‘’ COMMENT ‘录音标识’,
sign_code varchar(100) DEFAULT ‘’ COMMENT ‘签约业务编码’,
custom_id varchar(100) DEFAULT ‘’ COMMENT ‘平台客户’,
playback_sound_address varchar(200) DEFAULT ‘’ COMMENT ‘放音地址’,
bridge_flag int(1) DEFAULT NULL COMMENT ‘变号标识’,
valid_flag int(1) DEFAULT NULL COMMENT ‘有效标志’,
use_origin_call int(1) DEFAULT ‘0’ COMMENT ‘使用原主叫标志’,
use_origin_called int(1) DEFAULT ‘0’ COMMENT ‘使用原被叫标志’,
call_no varchar(50) NOT NULL DEFAULT ‘0’ COMMENT ‘主叫’,
called_no varchar(50) NOT NULL DEFAULT ‘0’ COMMENT ‘被叫’,
display_no varchar(50) NOT NULL DEFAULT ‘0’ COMMENT ‘显示号码’,
real_called_no varchar(50) NOT NULL DEFAULT ‘0’ COMMENT ‘被叫’,
route varchar(100) DEFAULT ‘’ COMMENT ‘下一跳地址’,
domain varchar(200) DEFAULT ‘’ COMMENT ‘域名’,
create_time varchar(100) DEFAULT ‘’ COMMENT ‘创建时间’,
create_user varchar(50) DEFAULT ‘’ COMMENT ‘创建人’,
modify_time varchar(100) DEFAULT ‘’ COMMENT ‘修改时间’,
modify_user varchar(50) DEFAULT ‘’ COMMENT ‘修改人’,
trace_flag int(1) DEFAULT ‘0’ COMMENT ‘跟踪标志’,
hangup_flag int(1) DEFAULT ‘0’ COMMENT ‘挂断标志’,
max_call_counts int(5) DEFAULT ‘1’ COMMENT ‘最大通话数’,
record_mode varchar(20) DEFAULT ‘0’ COMMENT ‘录音模式’,
before_connect_dtmf_flag int(1) DEFAULT ‘0’ COMMENT ‘53’,
before_connect_playback_sound_address varchar(200) DEFAULT ‘’ COMMENT ‘123’,
hangup_tone varchar(200) DEFAULT ‘’ COMMENT ‘123’,
max_dtmf_counts int(5) DEFAULT ‘4’ COMMENT ‘123’,
query_ctrl_flag int(1) DEFAULT ‘0’ COMMENT ‘访问ctrl标志’,
music_on_hold_flag int(1) DEFAULT ‘0’ COMMENT ‘标志’,
event_flag int(1) DEFAULT ‘0’ COMMENT ‘56’,
music_on_hold_class varchar(200) DEFAULT ‘’ COMMENT ‘68’,
data_binding_path varchar(200) DEFAULT ‘’ COMMENT ‘数据地址’,
value_added_service varchar(50) DEFAULT ‘0’ COMMENT ‘增值’,
data_binding_access_flag varchar(50) DEFAULT ‘0’ COMMENT ‘值为数字型字符串’,
suspend_number tinyint(4) NOT NULL DEFAULT ‘0’ COMMENT ‘’,
forbid_international tinyint(4) NOT NULL DEFAULT ‘0’ COMMENT ‘禁止呼叫’,
forbid_special_number_outcoming int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘禁止呼出’,
forbid_special_number_incoming int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘禁止呼入’,
forbid_color_ring tinyint(4) NOT NULL DEFAULT ‘0’ COMMENT ‘不支持’,
forbid_video tinyint(4) NOT NULL DEFAULT ‘0’ COMMENT ‘不支持’,
color_ring_addr varchar(100) NOT NULL DEFAULT ‘’ COMMENT ‘645’,
forbid_playback_sound_continue tinyint(4) NOT NULL DEFAULT ‘0’ COMMENT ‘66756’,
forbid_short_message tinyint(4) NOT NULL DEFAULT ‘0’ COMMENT ‘786’,
binding_timeout int(11) DEFAULT ‘1100’ COMMENT ‘超时时间,单位毫秒’,
proxy_media tinyint(4) NOT NULL DEFAULT ‘0’ COMMENT ‘代理’,
record_samping tinyint(4) NOT NULL DEFAULT ‘0’ COMMENT ‘抽样’,
reserve1_bit bit(64) NOT NULL DEFAULT b’0’ COMMENT ‘预留位操作字段1’,
reserve2_bit bit(64) NOT NULL DEFAULT b’0’ COMMENT ‘预留位操作字段2’,
reserve3_bit bit(64) NOT NULL DEFAULT b’0’ COMMENT ‘预留位操作字段3’,
reserve4_bit bit(64) NOT NULL DEFAULT b’0’ COMMENT ‘预留位操作字段4’,
reserve5_bit bit(64) NOT NULL DEFAULT b’0’ COMMENT ‘预留位操作字段5’,
reserve1_char varchar(100) NOT NULL DEFAULT ‘’ COMMENT ‘预留字符串操作字段1’,
reserve2_char varchar(100) NOT NULL DEFAULT ‘’ COMMENT ‘预留字符串操作字段2’,
reserve3_char varchar(100) NOT NULL DEFAULT ‘’ COMMENT ‘预留字符串操作字段3’,
reserve4_char varchar(100) NOT NULL DEFAULT ‘’ COMMENT ‘预留字符串操作字段4’,
reserve5_char varchar(100) NOT NULL DEFAULT ‘’ COMMENT ‘预留字符串操作字段5’,
PRIMARY KEY (sign_number,call_no,called_no,display_no,real_called_no) /*T![clustered_index] CLUSTERED */,
KEY custom_id (custom_id),
KEY sign_number (sign_number)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT=‘规则表’;

就你发的这一个执行计划来看应该不太具有代表性,这个里面耗时最多的是get_snapshot时间,应该当时raft租约到期等待选主过程。如果频繁的出现这种get_snapshot慢的情况,需要查看静默region是否被频繁的唤醒了,或者磁盘是否存在一些写入瓶颈等等。

最好多发几次explain analyze执行计划看看,主要瓶颈在哪里。一般情况下点查1-3ms能完成。

硬件环境是如何的呢?

mysql能解决的问题不用上tidb。

总共才520w条。2000w都不到,正好是mysql的理想数据范围内。
这个数据量考虑分布式属于过度设计。
就像随手开门前还要先考虑一下国际形势一样。十分多余。
再多2个数量级,到5.2亿,再考虑分布式。

2 个赞


第二次

第3次

第四次

第五次

补充一下dump信息
dump.txt (258.2 KB)

不能以不变的眼光看问题吧,我们现在是520w,后面1年就有可能过千万。
我们现在有的业务数据已经是每天都过5000w了,mysql完全扛不过来。
现在是要看是否能把查询速度提上来。我们也考虑多个方案,现在是比较哪个方案更好。看看tidb是否可以解决我们的问题

1 个赞

我们是在虚机上部署的,和mysql基本上一样的环境,硬盘配置应该是只高不低。主要是查询差距太大了。mysql一般都是1ms内返回,估计平均响应时间是0.7ms。即便是高并发情况下(2000qps)也能做到1ms返回。如果查询速度还不如mysql,那tidb在某些地方还是不能做到平替mysql。不知道我还能提供哪些信息,能帮我解决瓶颈问题

table-range-scan 想对比 mysql,TiDB 比 mysql 应该是预期的。只有 point get 能差不多接近 mysql 的效率。响应时间不那么复合 TiDB 的定位,特别当前只有几百万数据

打开监控 disk-performance 面板,看下磁盘响应时间和吞吐量

这个没看,我们是直接ssh过去,我找运维帮忙看一下,不过可以确定的是:这个机器在查询的时候,除了必要的监控,基本上没跑啥程序,就是单独的用来测试数据库的,新机器,环境问题可以忽略。

你这是抖动,你看不是每次都那么慢,跟磁盘有关,分布式数据库对磁盘和网络的要求高

TiDB 是自带监控的,为啥环境问题可以忽略呢 :joy_cat:

我用我们线上程序跑测试,连续请求每次都是7-8ms,第一次用时更长,达到35ms(我们程序50ms超时,35ms实际上已经是第二次了)。我们线上的mysql才1ms。这个差距实在是太大了

那您能提供监控和硬件配置让大家看下一起分析下吗?

还有如果上生产不要选 8.3 版本,选一个 LTS 版本

可以,你这边可以提供一下相关命令吗?我是centos,你想查哪些数据,可以发命令,我统一回复一个txt文件,你看行不?

通过中控机(就是你执行 tiup 安装命令那台机器)执行 tiup cluster display <cluster_name> 获取集群拓扑,把这个发下,然后结果中有个 Grafana url,通过这个登录到 Grafana(默认密码 admin/admin) ,查看 disk-performance 面板,选择 TiKV 机器地址



在红框时间段(我执行explain analyze)没有其他的写入,也没有其他读取