Tidb查询被阻塞,无法正常查询

你好: 1. 从执行计划来看,vip_service这张表过滤后执行计划估算还有225523254条记录, 之后和其他表3张表join。第一个product join完之后数据为281904068,第二个vip_growth join完之后有 281904068,第三个表order有 490041900行,join完之后有282468018, 这时还要做group, hashagg之后还有66268316。 从执行计划过程来看,单纯的就是数据量大。 2. 在迁移到tidb之前是使用什么跑这些sql的? 3. 这个sql实际执行后的sql数据量大概是 66268316这个值吗?

之前在mysql跑没有问题,只是比tidb要慢些,在没有升级之前出现问题,就是升级后才出现的。最终真实返回:1.6KW左右

像这么大的数据量查询,能解决不?慢点没事,不要被oom就行,用磁盘也可以。 后面把tidb加了32G swap,感觉就特别慢,完全跑不出来样的。不知道是否还有其它方法?

  1. 单机mysql还是分库分表查询后汇总的?
  2. 使用硬盘增加swap肯定会慢.
  3. 再查下这几个表的当前信息 select * from information_schema.TABLES where TABLE_SCHEMA=‘boss’ and table_name in (‘vip_service’,‘product’,‘vip_growth’,‘order’);
  4. 如果一条sql oom,业务侧是否可以分两条sql来跑,中间加一个过度的临时表,用完后,再删除?
  5. 有没有测试环境,加强制索引试一下走index lookup join能少消耗点内存.
root 14:50:  [(none)]> select * from information_schema.TABLES where TABLE_SCHEMA='boss' and table_name in ('vip_service','product','vip_growth','order');  
+---------------+--------------+-------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+-----------------+---------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME  | TABLE_TYPE | ENGINE | VERSION | ROW_FORMAT | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | AUTO_INCREMENT | CREATE_TIME         | UPDATE_TIME | CHECK_TIME | TABLE_COLLATION | CHECKSUM | CREATE_OPTIONS | TABLE_COMMENT   | TIDB_TABLE_ID |
+---------------+--------------+-------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+-----------------+---------------+
| def           | boss         | product     | BASE TABLE | InnoDB |      10 | Compact    |       9792 |            252 |     2476421 |               0 |       506529 |         0 |              1 | 2019-11-04 11:06:27 | NULL        | NULL       | utf8_bin        |     NULL |                |                 |          2960 |
| def           | boss         | vip_growth  | BASE TABLE | InnoDB |      10 | Compact    |   23935478 |             97 |  2345670312 |               0 |   1196767368 |         0 |              1 | 2019-04-30 16:20:48 | NULL        | NULL       | utf8_bin        |     NULL |                | 会员成长值      |           647 |
| def           | boss         | order       | BASE TABLE | InnoDB |      10 | Compact    |  491380433 |            199 | 98266191730 |               0 |  56004934346 |         0 |              1 | 2019-05-14 13:18:44 | NULL        | NULL       | utf8_bin        |     NULL |                |                 |           667 |
| def           | boss         | vip_service | BASE TABLE | InnoDB |      10 | Compact    |  292236423 |            196 | 57314922970 |               0 |  49157466396 |         0 |              1 | 2019-05-14 19:41:31 | NULL        | NULL       | utf8_bin        |     NULL |                |                 |           691 |
+---------------+--------------+-------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+-----------------+---------------+
4 rows in set (0.21 sec)

第5点加强制索引,怎么加?force index()?

对的,可以使用 force index()。

| │ │ │ └─Selection_64 | 225523254.66 | cop | eq(boss.v.status, 0), gt(boss.v.vip_end_time, 2019-11-17 00:00:00.000000), lt(boss.v.created_at, 2019-11-18 00:00:00.000000), lt(boss.v.vip_begin_time, 2019-11-18 00:00:00.000000), ne(boss.v.channel_uuid, "CCCCCCCCCCCC") 
| | │ │ │ └─TableScan_63 | 291659675.00 | cop | table:v, range:[0,+inf], keep order:false

force index 哪个索引,目前看这个是在tikv中执行(看是cop),用到索引了吧

table:v, range:[0,+inf],这边看着是没有用到索引的。

from vip_service v use index(union_vip_time_cate_user_uuid_index_101)

试一下

强制索引后,执行时间少了3分钟左右,手动执行两次没有出现问题。再观察下。有没有什么办法让它像mysql一样,自动生成临时表,不会被oom?

基于 oom 的考虑,除了使用 cancel 这种方式来防止 tidb-server 的 oom,或者从业务侧对一些已知的大 SQL 进行拆分和优化下语句,看是否是索引不正确或者没用到索引。

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