你好: 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,感觉就特别慢,完全跑不出来样的。不知道是否还有其它方法?
- 单机mysql还是分库分表查询后汇总的?
- 使用硬盘增加swap肯定会慢.
- 再查下这几个表的当前信息 select * from information_schema.TABLES where TABLE_SCHEMA=‘boss’ and table_name in (‘vip_service’,‘product’,‘vip_growth’,‘order’);
- 如果一条sql oom,业务侧是否可以分两条sql来跑,中间加一个过度的临时表,用完后,再删除?
- 有没有测试环境,加强制索引试一下走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 分钟后被自动关闭。不再允许新回复。