MySQL子查询优化

起因

  以前用oracle.换了公司以后接触mysql也差不多半年了..对于子查询有一些想法,感觉稍微不注意一点..就会不走索引,让SQL变的很慢...所以记录一下特别需要注意的地方

 

具体

看个很简单的例子

1个查询,用ID去过滤数据,数据来自子查询,子查询的量大约40W+. ID上面是有索引的..

这个查询用了4.169S..结果只有16条数据而已....

看执行计划:

1.查询T表所有数据用索引和A表关联,得到40W+数据.

2.外层查询用索引去过滤这些数据得到结果

 

优化以后:

一样的结果,但是这个查询只用0.007S就得到了结果.....

看执行计划:

1.先走索引过滤T表数据得到1行结果,然后和A表用索引左连接.

2.外层查询取内层查询的所有数据

 

例子2:

这个SQL里....红框的执行计划对应的是SQL里日期条件的过滤...内部子查询查出数据以后在外部SQL里用日期过滤.

但是执行计划里看这里没有走索引...type是ALL........

 

优化以后:

内部查询日期过滤是可以走索引的..(不过这里没有走..因为数据比较集中..条件日期稍微改下就可以走索引了)....相比之前的SQL,子查询就可以过滤掉很多数据...

 

 

小结

SQL有子查询的时候尽量把子查询的过滤条件写到子查询里做掉.而不是到外层...MYSQL不会自己做优化.(ORACLE就会)...

另外嵌套查询最好不要写太多层..多写1个select * from (XXXX)可能就会对性能有一些影响....

这些问题在用mybatis写SQL...用<sql>标签复用代码的时候很容易出现,需要注意...

 

转载于:https://www.cnblogs.com/abcwt112/p/7693657.html

MySQL子查询的结果集较大时,会导致性能问题,下面给出MySQL子查询优化案例。 原始SQL语句: ``` SELECT * FROM orders WHERE customer_id IN ( SELECT customer_id FROM customers WHERE first_name = 'John' ) ``` 这个查询会返回与名为“John”的客户关联的所有订单。但是,如果子查询中匹配的客户数量很大,此查询可能会变得非常缓慢。 优化SQL语句: ``` SELECT o.* FROM orders AS o INNER JOIN customers AS c ON o.customer_id = c.customer_id WHERE c.first_name = 'John' ``` 这个查询使用 INNER JOIN 来连接订单和客户表,然后使用 WHERE 子句来过滤出客户名为“John”的订单。这个查询不使用子查询,而是直接连接两个表,因此可以避免子查询中的性能问题。 可以使用 EXPLAIN 关键字来查看查询计划,并确定查询是否使用了索引。下面是第二个查询的 EXPLAIN 输出: ``` +----+-------------+-------+------------+-------+---------------+---------+---------+----------------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+----------------+------+----------+-------------+ | 1 | SIMPLE | c | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | Using index | | 1 | SIMPLE | o | NULL | ref | customer_id | customer_id | 4 | sampledb.c.customer_id | 2 | 100.00 | NULL | +----+-------------+-------+------------+-------+---------------+---------+---------+----------------+------+----------+-------------+ ``` 可以看到,查询使用了客户表的主键(PRIMARY)来过滤出名为“John”的客户,然后使用订单表的 customer_id 索引来过滤出相关订单。这个查询的性能比第查询要高得多。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值