本文介绍: 首先,根据创建索引指定索引长度截取条件中的的对应长度字符取索引中获取一次出现该索引的id然后区聚集索引中根据id获取到行信息,从行信息获取对应字段信息语句中的信息对比,如果相同,则返回该行信息可以根据索引的选择性来决定,而选择性是指不重复的索引值(基数)和数据表记录总数的比值,索引选择性越高则查询效率越高,唯一索引的选择性是1,这是最好的索引选择性性能也是最好的。比如说,name字段存在单列索引,也和agesex存在联合索引,那么在只查询name字段时,可能会走联合索引。

目录

SQL性能分析

SQL执行频率

慢查询日志

profile详情

explain执行计划


SQL性能分析

这里我们可以看到一张表主要是进行哪些操作。 

慢日志记录存储位置为/var/lib/mysql/localhostslow.log

开启之后可以执行如下语句

语法

字段解释

id: select查询的序列号,表示查询中执行select子句或是操作表的顺序,执行顺序从上到下(id相同,从上到下,id不同,值越大越先执行)

select_type表示 SELECT 的类型,常见的取值有 SIMPLE(简单表,即不使用连接或者子查询)、PRIMARY(主查询,即外层的查询)、UNION(UNION 中的第二个或者后面的查询语句)、SUBQUERY (SELECT/WHERE之后包含了子查询)等

type表示连接类型,性能由好到差的连接类型为NULL、systemconst、eg_refrefrangeindexall。

possible_key显示可能应用在这张表上的索引,一个多个

key表示实际使用的索引,如果为NULL,则没有使用索引。

key_len表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好

rowsMySQL认为必须要执行查询的行数,在innodb引擎表中,是一个估计值,可能并不总是准确的。

filtered:表示返回结果行数占需读取行数的百分比,filtered 的值越大越好

extra额外信息

使用语法

  • using where;using index:使用了索引,但是需要的数据在索引列中可以找到,不需要进行回表查询
  • using index condition:使用了索引,但是需要回表查询

语法

前缀长度选择

前缀索引查询流程

  1. 针对数据量较大(百万级时),且查询比较频繁的表建立索引。
  2. 针对于常作为查询条件 (where)、排序(order by)、分组 (group by) 操作的字段建立索引。
  3. 尽量选择区分度高(比如说手机号邮箱等)的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。
  4. 如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引。
  5. 尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表提高查询效率。
  6. 控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率。
  7. 如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它。当优化器知道每列是否包含NULL值时,它可以更好地确定哪个索引最有效地用于查询。

先来查看一种主键顺序插入的情况

如果主键乱序插入的话,则是另一种情况

  • 根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则。
  • 尽量使用覆盖索引。
  • 多字段排序,一个升序一个降序,此时需要注意联合索引在创建时的规则(ASC/DESC)。
  • 如果不可避免的出现filesort,大数据量排序时,可以适当增大排序缓冲大小sort_buffer_size(默认256k)。
select age,sex,count(*) from user group by age,sex;

时,我们可以通过索引拿到对应的数据,因此效率就高,如果执行

select age,sex,count(*) from user group by sex;

时,不满足最左前缀法则,因此需要走临时表,但是如果执行的是

select age,sex,count(*) from user where age =18 group by sex;

时,走的也是索引,因为我们对age进行了过滤用到了age索引。

select * from user limit 2000000,10;

通过索引拿到10条数据的id。然后通过另一条查询语句获取这十条数据的信息。

select u.* from user u,(select id from user limit 2000000,10) l where l.id = u.id;

count(主键):统计记录数。

count(字段):统计该字段不为NULL的数量。

count(1):只要查询一条记录不为null。那么便返回1。

count(*):记录记录数。

update user set name = "张三" where id =1;

update user set name = "李四" where id =2;

那么接下来如果并发如下语句

update user set name = "张三" where id =1;

update user set name = "李四" where name = "王五";

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注