Mysql优化——SQL语句优化

索引优化

where 字段、组合索引(最左前缀)、索引下推(非选择行 不加锁)、索引覆盖(不回表)、on两边、排序、分组…explain分析语句情况,看建立索引没,或者建立错误,响应时间长的话可以看下慢查询日志

尽量不要用 *

查所有字段的话,select查询列中的字段如果没有索引的话,会造成回表

LIMIT优化

limit优化的特点是截断,就是可以停止全表扫描的,比如下面这个,肯定没走索引的,1000W条数据,就走了20条,截断了
在这里插入图片描述
原SQL
在这里插入图片描述
这种sql语句和索引都没关系了,可以对他进行优化,可以创建个索引或者利用主键索引(根据业务设计),利用索引的排序或者where条件快速定位和limit截断的能力,让他缩小扫描范围
在这里插入图片描述在这里插入图片描述
还可以利用小结果集关联大结果集

count优化

count () 找普通索引 ,找到最小的那棵树来遍历,包含空值(mysql优化其实现,5.6版本)
在这里插入图片描述
count(1)和count(id)都是找到最小的那颗索引树,因为innodb的聚集索引,非主键索引下面挂载的是id的值,所以会选择一个小的索引树,因为主键索引下面挂载的是行数据,比非主键索引还是要大些的
在这里插入图片描述
count(非索引字段),找不到索引树
在这里插入图片描述
前面这几个count,如果是count(
),不会将这个数据缓存起来,这是innodb的特点,count()都是临时计算。如果是count(字段)的话,是可以缓存的。count()包含了空值的,count(字段)没有包含空值,count(1)和count()是一样的,忽略字段,包含空值
在这里插入图片描述

不用 MySQL 内置的函数,因为内置函数不会建立查询缓存

比如: SELECT * FROM user where birthday = now();

其他的一些游优化
  • 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引
  • 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select * from t where num is null可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select * from t where num=0
  • 应尽量避免在 where 子句中使用!=或<>操作符,如果查询列中包含索引以外的字段,将引擎放弃使用索引而进行全表扫描
  • 应尽量避免在 where 子句中使用 or 来连接条件,如果查询列中包含索引以外的字段将导致引擎放弃使用索引而进行全表扫描,如: select * from t where num=10 or num=20 -->select * from t where num=10 union all select * from t where num=20
    在这里插入图片描述
  • like模糊查询时百分号在前面也要导致索引失效,这种情况可以建立组合索引,查询组合索引列
  • 应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:select * from t where substring(name,1,3)=‘abc’–name以abc开头的id 应改为:select * from t where name like ‘abc%’
  • 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引
  • 在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致
  • 并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用
  • 索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定
  • 一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要
  • 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销,这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了
  • 尽可能的使用 varchar 代替 char ,因为首先变长字段存储空间小,可以节省存储空间, 其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些
  • 任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段
  • 避免频繁创建和删除临时表,以减少系统表资源的消耗
  • 临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表
  • 合适的情况编写存储过程,减少连接数据库的次数
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值