【mysql】基础语法/索引部分优化

本文围绕MySQL数据库性能优化展开,从减少访问数据、返回更少数据等多方面提出优化思路,总结为最大化合理化利用索引和避免全表扫描等两点。还介绍了SQL语法优化方法,如in、exists等的使用,以及索引失效的多种情况,为MySQL性能提升提供参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文前半部分详情请跳转原文:https://blog.youkuaiyun.com/m0_56864757/article/details/125217302

针对于mysql的优化主要是考虑一下几个方面:

  1. 减少访问的数据:合理字段类型,合理使用索引减少磁盘IO。
  2. 返回更少数据:杜绝返回大量不需要数据,增加io以及网络io。
  3. 减少交互次数:可以批量操作的尽量DML批量操作。
  4. 减少cpu开销:减少排序等的不必要的复杂操作以及全表查询减少cpu内存占用。
  5. 利用更资源:可以使用分区操作,增加并行操作,更大限度利用CPU。

主要总结为两点:

  1. 最大化合理化利用索引。(不可以无脑上索引需要看维护成本)
  2. 避免全表扫描以及无效数据的额外查询。

mysql语法部分优化:

1.sql语句中in后面如果是子查询话,会导致全表扫描,因为子查询的结果是未知的,不可以作为外层的索引判断。情况2:in后续跟的是固定的值(1,2,3)这种形式,如果包含的值很多索引失效。

解决:如果后续的固定值是连续的值的话,可以用between代替。如果in后续跟的是子查询,可以用关联的方式代替in(效率会高很多)。

2.Select查询必须指明字段,减少返回额外数据。

3.限制条件中有其他字段没有索引,减少使用or。(或者用union代替)

4.Union和union all的使用。不涉及去重使用union。Union all需要合并进行唯一性条件过滤,涉及到排序等的操作增加cpu消耗。

In 和 exists not in not exists 以及  inner join

5.in和exists以及not in 和 not exists的使用:

In和exists 最大的区别是谁驱动的问题,不能说exists 的效率一定比in高。in的驱动表是子查询,而exists 的驱动表是 外层表。所以 子查询数据比较小用in,外层数据小用exists 。(in是将子查询的id和外层做hash连接,exists 是循环外层然后再对内表进行查询)

6.not in 和not exists的使用:

Not in内外表都会扫描没有用到扫描,所以不管那个表大,not  exists的效率都更高。(not  exists 的子查询可以使用索引)

7.in 和 join:

结果集比较小的情况下,in的效率更高。结果集较大,join的效率优于in。

子查询有创建临时表删除临时表的过程。

总结:小数据量几种方式的差距不是很明显,大数据量下

Join 高于 exists 和in   (exists 和in 取决于那个是驱动表)

Join高于 not exists  高于 not in

8.where过滤判断null,like 模糊查询 ‘%%’ 数值头部迷糊查询。。。详情看下面的索引失效情况整理。

9.索引失效:联合索引,其中一个字段有 between 等的 范围查询,索引失效

10.驱动表优化:关联问题,尽可能使用小表驱动大表。Inner join默认数据量小的表作为小表。

驱动表循环遍历次数越少,会减少io和cpu的压力。

11.分页优化:数据量大的时候 直接  limit  1000000,20 比较慢,可以 >100000 limit 20。

下面整理了一些索引会失效的情况:

本文后半部分原文详情请跳转:你知道mysql哪些查询情况不走索引吗_Mysql_脚本之家

语法上针对索引优化主要是考虑索引失效的情况:

1.索引列如果在where等的条件后 有计算,不走索引。

举例:  where   money+10=20;(不走索引)

2.索引列应用了函数,可能不走索引

举例: where  concat(name,’tmp’)=zytmp;(不走索引)

举例: where  name=concat(zy,’tmp’);(走索引)

可以将函数等的操作放在等号后面的值上面,避免函数操作索引列。

3.索引列使用了like模糊查询,可能不走索引。

Like模糊查询不能从头开始模糊查询,会导致索引失效。如果直走尾部模糊查询,可以走索引。

举例: where name like  ‘%jack%’; (不走索引)

where name like  ‘jack%’; (模糊查询只模糊尾部,走索引)

4.数据有隐式转换即数据类型不一致(字符串和数字类型直接比较),不走索引。

5.Where 后续的过滤有or关键字,只要是or连接的字段,有一个字段没有索引,整个语句就不走索引。

6.where 过滤时出现不等于(!= 或者 <>)的操作:

Where   id!=2  或者  Where   id<>2 (不走索引)

7.出现空值的判断 is  null,is not null的情况,不走索引。

8.索引列使用in语句,in的数据量大的时候不走索引。

举例: where  name in  (‘jack’);(走索引)(name是varchar类型)

where  name in  (123);(不走索引)(数据类型不一致)

Where   name in  (大量数据);(不走索引)
9.查询结果集是原表的大部分数据,应该是 25%以上,就不走索引了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值