记一次子查询导致索引失效问题

今天发现有一天sql查询很慢,大概是这样的

SELECT * FROM dang_user WHERE id in(SELECT MAX(id) FROM dang_user WHERE if_use = 1 GROUP BY dang_username)

 解析发现,这个语句没走索引,这里面的字段都是有索引的,后来强制 FORCE INDEX(id),还是不行,为什么呢,百度了一下,有两个知识点

第一个知识点:Mysql在处理所有的查询的时候都强行转换为联接来执行,将每个查询包括多表中关联匹配,关联子查询,union,甚至单表的的查询都处理为联接,接着Mysql执行联接,把每个联接在处理为一个嵌套循环;
第二个知识点:在Mysql在处理子查询的时候,会将子查询改写,Mysql将会扫描外查询中的所有数据,每条数据都将会传到子查询中进行关联,子查询不能首先被执行,如果外表很大的话,那么性能上将会出现问题。

后来改成这样

select d.*
from (select MAX(id) id from dang_user WHERE if_use = 1 GROUP BY dang_username) as o inner join dang_user d on o.id = d.id

发现索引起效果了

子查询是 SQL 中的一种查询方式,它可以在一个查询中嵌套另一个查询。对于同一张表的多次子查询,由于需要反复访问同一张表,因此可能会导致查询效率低下。 为了提高查询效率,可以考虑使用联合查询(UNION)或者联合子查询(UNION ALL)。联合查询可以将多个查询结果合并为一个结果集,而联合子查询则可以在一个子查询中嵌套多个子查询,从而减少对同一张表的多次访问。 举个例子,假设我们有一个用户表 users,其中包含用户的 id、name 和 age。现在我们要查询年龄最大的前三个用户的姓名和年龄,可以使用以下 SQL 查询语句: ``` SELECT name, age FROM users ORDER BY age DESC LIMIT 3; ``` 但是,如果我们要同时查询年龄最小的前三个用户的姓名和年龄,可以使用子查询: ``` SELECT name, age FROM users WHERE age IN ( SELECT age FROM users ORDER BY age ASC LIMIT 3 ) ORDER BY age ASC; ``` 这个查询语句中包含了两个子查询,分别用于查找年龄最小的前三个用户和查询他们的姓名和年龄。这样的查询可能会导致效率低下,因为需要反复访问同一张表。为了提高查询效率,可以使用联合查询: ``` SELECT name, age FROM ( SELECT name, age FROM users ORDER BY age DESC LIMIT 3 ) AS max_age UNION ALL SELECT name, age FROM ( SELECT name, age FROM users ORDER BY age ASC LIMIT 3 ) AS min_age; ``` 这个查询语句中使用了联合查询,将年龄最大的前三个用户和年龄最小的前三个用户的结果合并为一个结果集。这样就可以避免反复访问同一张表,提高查询效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值