MYSQL索引优化

1.查看sql的执行频率

        MySQL 客户端连接成功后,通过 show [session|global] status 命令可以提供服务器状态信息。show [session|global] status 可以根据需要加上参数“session”或者“global”来显示 session 级(当前连接)的计结果和 global 级(自数据库上次启动至今)的统计结果。如果不写,默认使用参数是“session”。

2.定位效率底下的sql

可以通过以下两种方式定位执行效率较低的 SQL 语句。

慢查询日志 : 通过慢查询日志定位那些执行效率较低的 SQL 语句,用--log-slow-queries[=file_name]选项启 动时,mysqld 写一个包含所有执行时间超过 long_query_time 秒的 SQL 语句的日志文件。具体可以查看本 书第 26 章中日志管理的相关部分。

show processlist : 慢查询日志在查询结束以后才纪录,所以在应用反映执行效率出现问题的时候查询慢查询 日志并不能定位问题,可以使用show processlist命令查看当前MySQL在进行的线程,包括线程的状态、是否 锁表等,可以实时地查看 SQL 的执行情况,同时对一些锁表操作进行优化。

3.explain分析执行计划

MYSQL索引优化_第1张图片

type 显示的是访问类型,是较为重要的一个指标,可取值为:

MYSQL索引优化_第2张图片

一般来说, 我们需要保证查询至少达到 range 级别, 最好达到ref 。

Mysql从5.0.37版本开始增加了对 show profiles 和 show profile 语句的支持。show profiles 能够在做SQL优化时 帮助我们了解时间都耗费到哪里去了。

4.索引的使用

如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始,并且不跳过索引中的列。 匹配最左前缀法则,走索引。

不要在索引列上进行运算操作, 索引将失效。 

字符串不加单引号,造成索引失效。

尽量使用覆盖索引(只访问索引的查询(索引列完全包含查询列)),减少select * 。

用or分割开的条件, 如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。

以%开头的Like模糊查询,索引失效。 如果仅仅是尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引失效。通过覆盖索引可解决。

如果MySQL评估使用索引比全表更慢,则不使用索引。

 in 走索引, not in 索引失效。

is NULL , is NOT NULL 有时索引失效。

尽量使用复合索引,而少使用单列索引 。单列索引数据库会选择一个最优的索引(辨识度最高索引)来使用,并不会使用全部索引 。

5.插入数据优化

对于 InnoDB 类型的表,有以下几种方式可以提高导入的效率:

因为InnoDB类型的表是按照主键的顺序保存的,所以将导入的数据按照主键的顺序排列,可以有效的提高导入数 据的效率。如果InnoDB表没有主键,那么系统会自动默认创建一个内部列作为主键,所以如果可以给表创建一个 主键,将可以利用这点,来提高导入数据的效率。

在导入数据前执行 SET UNIQUE_CHECKS=0,关闭唯一性校验,在导入结束后执行SET UNIQUE_CHECKS=1,恢 复唯一性校验,可以提高导入的效率。

如果应用使用自动提交的方式,建议在导入前执行 SET AUTOCOMMIT=0,关闭自动提交,导入结束后再执行 SET AUTOCOMMIT=1,打开自动提交,也可以提高导入的效率。

insert优化:

如果需要同时对一张表插入很多行数据时,应该尽量使用多个值表的insert语句,这种方式将大大的缩减客户 端与数据库之间的连接、关闭等消耗。使得效率比分开执行的单个insert语句快。

在事务中进行数据插入。

数据有序插入。

6.order by语句优化:

两种排序方式

1). 第一种是通过对返回数据进行排序,也就是通常说的 filesort 排序,所有不是通过索引直接返回排序结果的排序 都叫 FileSort 排序。

2). 第二种通过有序索引顺序扫描直接返回有序数据,这种情况即为 using index,不需要额外排序,操作效率高。

了解了MySQL的排序方式,优化目标就清晰了:尽量减少额外的排序,通过索引直接返回有序数据。where 条件 和Order by 使用相同的索引,并且Order By 的顺序和索引顺序相同, 并且Order by 的字段都是升序,或者都是 降序。否则肯定需要额外的操作,这样就会出现FileSort。

如果查询包含 group by 但是用户想要避免排序结果的消耗, 则可以执行order by null 禁止排序。

7.优化嵌套查询

Mysql4.1版本之后,开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把 这个结果作为过滤条件用在另一个查询中。使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL 操作,同时也可以避免事务或者表锁死,并且写起来也很容易。但是,有些情况下,子查询是可以被更高效的连接 (JOIN)替代。连接(Join)查询之所以更有效率一些 ,是因为MySQL不需要在内存中创建临时表来完成这个逻辑上需要两个步骤的 查询工作。

  1. 优化OR条件

对于包含OR的查询子句,如果要利用索引,则OR之间的每个条件列都必须用到索引 , 而且不能使用到复合索 引; 如果没有索引,则应该考虑增加索引。UNION 语句的 ref 值为 const,OR 语句的 type 值为 null,const 表示是常量值引用,非常快 这两项的差距就说明了 UNION 要优于 OR 。

9.优化分页查询

一般分页查询时,通过创建覆盖索引能够比较好地提高性能。在索引上完成排序分页操作,最后根据主键关联回原表查询所需要的其他列内容。也可以对于主键自增的表,可以把Limit 查询转换成某个位置的查询 。

你可能感兴趣的