首页 新闻 会员 周边

mysql的sql语句优化查询

0
[已解决问题] 解决于 2022-05-23 14:51

SELECT MAX(id) FROM gps WHERE cardId IN () GROUP BY cardId ;

这是一张近千万条数据的表,根据cardId查询然后分组获取最大的主键 id,查询时间需要十几秒,效率特别的低,有什么优化SQL语句的方法吗?

xx_1234的主页 xx_1234 | 菜鸟二级 | 园豆:243
提问于:2022-05-19 10:49
< >
分享
最佳答案
0

另辟蹊径:新建一个表,这个表两个字段:MaxId和CardId。当gps执行insert或delete操作时,更新一下这个表。这样你就不用去gps表里查数据了,直接来这个表里查。

奖励园豆:5
会长 | 专家六级 |园豆:12401 | 2022-05-19 16:15

不是在insert的时候,才来执行这个SQL的,是按照用户查询的需求,来实时查询的,例如用户想看一百个员工(最大只有七八百个)的gps表中的Max(Id)数据,就在in里边拼接上cardId查询。

xx_1234 | 园豆:243 (菜鸟二级) | 2022-05-19 16:56

还有一个时间的选择,不一定是看当前时间的最大值,也可能通过时间选择,查看到所选时间的最大值

xx_1234 | 园豆:243 (菜鸟二级) | 2022-05-19 17:02

@xx_1234: 我的意思是当对表gqs进行插入或删除操作时,同时对新建的表(假设叫做t)进行update或insert操作。举例:

当往gqs插入一条数据{id=100,cardid=200}后,往t表也插入一条数据{maxid=100,cardid=200},如果此表中已经存在cardid=200的数据,则执行 update t set maxid=100 where cardid=200。

用户想查询carid为200和300的数据时,不需要再去表gps查了,而是去表t查:

select maxid, cardid from t where cardid in (200,300)
会长 | 园豆:12401 (专家六级) | 2022-05-19 17:04

@会长: 这种方法是做的有的,只对查看当前时间的数据有效,但是选择过去的时间,查看以前的数据,就不得行了

xx_1234 | 园豆:243 (菜鸟二级) | 2022-05-19 17:12
其他回答(2)
0

cardId IN () IN 中大概有多少条记录?

dudu | 园豆:30994 (高人七级) | 2022-05-19 11:04

最多只有7-8百条,一般是在3-4百条左右

支持(0) 反对(0) xx_1234 | 园豆:243 (菜鸟二级) | 2022-05-19 11:07

@xx_1234: 建议将 IN () 中数据保存在临时表中,然后 join 临时表

cardId 字段如果没有加索引,需要加上

支持(0) 反对(0) dudu | 园豆:30994 (高人七级) | 2022-05-19 12:11

@dudu: 设置索引了的,in里边的数据是用户需求实时查询出来的,没办法建临时表来保存

支持(0) 反对(0) xx_1234 | 园豆:243 (菜鸟二级) | 2022-05-19 16:48

@xx_1234: 查询之前插入临时表,查询之后删除临时表

支持(0) 反对(0) dudu | 园豆:30994 (高人七级) | 2022-05-19 17:04

@dudu: 我做了测试的,in里边的数据查询的很快(几十毫秒),主要还是那个SQL语句查询的很慢

支持(0) 反对(0) xx_1234 | 园豆:243 (菜鸟二级) | 2022-05-19 17:16

@xx_1234: 试试外面套一层或者在代码里查max?

支持(0) 反对(0) 王筱飞 | 园豆:200 (初学一级) | 2022-05-20 10:25
0

cardId 设置索引

talentzemin | 园豆:759 (小虾三级) | 2022-05-19 11:49

设置索引了的

支持(0) 反对(0) xx_1234 | 园豆:243 (菜鸟二级) | 2022-05-19 16:48

@xx_1234: 查看执行计划

支持(0) 反对(0) talentzemin | 园豆:759 (小虾三级) | 2022-05-19 22:55
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册