如下图,mysql 慢日志记录到的查询语句,目前 mysql 的 CPU 使用率达 70%左右
目前这个 d_lampblack_real_time 表中有 2000W 行的数据,请教下各位大佬该如何优化下。
1
xuanbg 2020-12-29 08:52:37 +08:00 1
执行计划发出来
|
2
huichao 2020-12-29 09:00:56 +08:00 1
你的 avg, 单独写在一个 function 可能会好点儿, 所有的查询,基本都是先加条件拿出来较少的数据,再来进行其他的逻辑操作,会快很多。
|
5
yeqizhang 2020-12-29 09:09:57 +08:00 via Android 1
别问,问就是加索引
|
6
l00t 2020-12-29 09:10:04 +08:00 1
表里总共 2000 多万数据,你查个 5 分钟也扫了 2000 多万,我怀疑你是不是没加索引。
|
7
aitaii 2020-12-29 09:12:48 +08:00 via iPhone 1
2000 万不应该这么慢,explain 看看,索引该加加,别乱加就行
|
8
lijialong1313 2020-12-29 09:13:39 +08:00 1
|
9
aitaii 2020-12-29 09:14:37 +08:00 via iPhone 1
另外 oltp 做统计很蛋疼,交给 olap 去做
|
10
totoro52 2020-12-29 09:21:20 +08:00 1
不要 1=1 必全表扫描 explain 看下执行计划
|
11
zhaokun 2020-12-29 09:28:52 +08:00 1
根据条件先查 ID,拿到 ID 集合再拿其他信息,avg 可以考虑放到代码实现
|
14
yveJohn 2020-12-29 09:51:47 +08:00 1
@lopetver #3 执行计划不是说 sql 多久执行一次,而是通过 mysql 的 explain 关键字查看 SQL 在数据库中执行时的表现.如 explan select * from table;
|
15
securityCoding 2020-12-29 09:58:52 +08:00 1
@zhaokun monitor_time 有索引的话会回表的 , 楼主这个不发执行计划就只能去瞎猜了
|
16
lopetver OP @xuanbg
@yveJohn 执行结果如下 MySQL [lampblack]> explain select * from d_lampblack_real_time; +----+-------------+-----------------------+------------+------+---------------+------+---------+------+---------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------------------+------------+------+---------------+------+---------+------+---------+----------+-------+ | 1 | SIMPLE | d_lampblack_real_time | NULL | ALL | NULL | NULL | NULL | NULL | 5254449 | 100.00 | NULL | +----+-------------+-----------------------+------------+------+---------------+------+---------+------+---------+----------+-------+ 1 row in set, 1 warning (0.02 sec) |
17
ymz 2020-12-29 10:00:09 +08:00 1
1 = 1,查询字段又不仅仅是索引字段,估计扫全表了
|
18
kimqcn 2020-12-29 10:03:06 +08:00 1
参考一个类似的老问题:根据 IP 查地址。
|
20
raptor 2020-12-29 10:05:04 +08:00 1
两步:explain, 加索引
|
21
x66 2020-12-29 10:05:23 +08:00 2
全表扫描了,给 monitor_time 加个索引,查询的时候再给时间字符串外面包一个 str_to_date('2020-12-21 15:15:00',’%Y-%m-%d %H:%i:%s’)
|
22
ETO 2020-12-29 10:05:40 +08:00 1
@lijialong1313 我们以前项目也是这么用的,为了加 and 条件方便,直接无脑拼接 SQL,而且这个对会被优化器优化掉的吧,应该。
|
23
pabupa 2020-12-29 10:06:26 +08:00 via Android 1
flink 吧,做统计的话。
或者 canal 自己算。 只用 mysql 的话,再怎么优化也就那样啊。 |
24
securityCoding 2020-12-29 10:06:46 +08:00 1
@lopetver 拿你的业务 sql 执行计划
|
25
sidong1993 2020-12-29 10:07:02 +08:00 1
@lopetver 发你有问题的 sql 语句的执行计划啊。你发的 select * from d_lampblack_real_time,这个语句执行计划又看不出啥
|
26
ymz 2020-12-29 10:07:45 +08:00 1
1 = 1 会被优化
|
27
lopetver OP |
28
SjwNo1 2020-12-29 10:14:05 +08:00 1
什么版本的 mysql, explain 显示没索引。。
|
29
lopetver OP |
30
ymz 2020-12-29 10:35:21 +08:00
lampblack_01 这个联合索引会不会有点太大,type=index,是二级索引全表扫描,难道你那么多查询字段都在联合索引里?
|
31
securityCoding 2020-12-29 10:38:29 +08:00
啰嗦一下 ,我提个小建议,v2 这里对于解决问题都是比较热情的,前提是希望你能清晰描述你的问题 , 如果我提类似问题的时候我会这样准备问题资料
1. mysql 版本 2. 业务表的 ddl ,以及数据量 3. 业务 sql 以及执行计划 |
32
lopetver OP |
33
junan0708 2020-12-29 10:57:08 +08:00
rows_examined 27379421 扫描的记录数
|
34
sidong1993 2020-12-29 14:40:42 +08:00
感觉是全表扫了,lampblock_01 索引包含了哪些列,时间加个索引?然后考虑考虑一些数据处理流程放在应用里去做?
|
35
mingszu 2020-12-29 14:43:08 +08:00
@lopetver 能看看 lampblack_01 的索引信息吗? show index from d_lampblack_real_time
|
36
lopetver OP @mingszu
+-----------------------+------------+--------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +-----------------------+------------+--------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | d_lampblack_real_time | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | | | d_lampblack_real_time | 0 | lampblack_01 | 1 | equipment_code | A | 0 | NULL | NULL | | BTREE | | | | d_lampblack_real_time | 0 | lampblack_01 | 2 | monitor_time | A | 0 | NULL | NULL | | BTREE | | | | d_lampblack_real_time | 1 | lampblack_02 | 1 | fs | A | 0 | NULL | NULL | YES | BTREE | | | | d_lampblack_real_time | 1 | lampblack_02 | 2 | ps | A | 0 | NULL | NULL | YES | BTREE | | | +-----------------------+------------+--------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 5 rows in set (0.00 sec) 现在已经把这个业务停了,应该看不出来原因了。回头再用了,这边再看下吧 |
37
ymz 2020-12-29 15:38:50 +08:00
@mingszu lampblack_01 这个联合索引只有两个字段,执行计划的 type 怎么会是 index,大佬知道为什么么?
|
38
sampeng 2020-12-29 18:25:01 +08:00 via iPhone
哎…你就一个 where 条件。加索引优化是多难?现在写代码这么难了么?
另外如果你是 5.7 以前的版本,时间加索引没什么用。5.7 以后有倒排索引。这是其一。 其二,group 用程序实现…4000 万数据集还让 mysql 干这么重的事昂? |
39
taogen 2020-12-29 19:48:01 +08:00 via Android
同楼上,where 加索引,group 在程序中做。
|
40
vindurriel 2020-12-29 20:18:23 +08:00 via iPhone
索引是(code, time) ,查询是 1. range of time, 2. group by code
建议把索引调换一下顺序试试(time, code) |
41
lijialong1313 2020-12-30 09:33:16 +08:00
@ETO 如果真的无脑拼接其实反过来更好,就是 XXX AND XXX AND 1=1
|