学习笔记:SQL优化(语句分析,EXLAPIN分析,性能分析)

SQL优化

总结一下网上学习的SQL优化方式,主要针对慢SQL进行优化。

语句分析

了解:
B树和B+树:B树的每个节点都会存储数据和索引,当寻找数据的时候,树内节点会产生IO,没有固定的时间复杂度,最好的为O(1)。B+树的数据都存放在叶子节点,非叶节点存放索引,能存放更多的索引,定位数据更精确,减少了磁盘的IO消耗。另外,B+树叶子节点都有引用指针,按照顺序引入,所以B+树更适合查找连续范围的数据。
mysql有两种引擎:innodb和myisam。innodb使用的是聚集索引,其数据文件和索引文件在同一个文件中,后缀为idb;而myisam使用的是非聚集索引,其数据文件和索引文件是分开的myd,myi。innodb通过聚集索引(主键)查找数据时候,可以直接找到数据并返回,当查找的字段是非聚集索引(其他字段)会进行回表操作,在非聚集索引文件中找到主键,再用主键再聚集索引文件中找到对应的数据。
innodb默认行锁。表锁情况是当通过一个没有索引的字段“更新”数据,此时表就会成为表锁。因为上锁是根据索引字段有关的一系列数据进行上锁的,当没有索引,就会将整个表上锁。
**避免回表:**在select后的字段带有聚集索引(主键)和该查找字段的时候,就不会回表,因为在非聚集索引文件中是带有主键的,所以不用回表就能获取主键;其次是建立联合索引(覆盖索引)也不用回表,其道理和前面一样,前面也是可以理解为覆盖索引,覆盖索引一般为多个字段一起建立的。

优化点:

  1. 对于连续值,用between on,而不是in。
  2. 查找字段,最好写明哪几个字段,而不是用*。
  3. 避免在where后对null进行判断。
  4. 避免在where后对字段进行表达式和函数操作。
  5. 联合索引需遵守最左匹配原则,当出现between,<,>等符号后,后续索引会失效。
  6. 能使用inner join就不使用left join,因为inner会使用最小表作为驱动表连接其他表,left是使用左表作为驱动表。
  7. 模糊匹配时候%不作为前置。
  8. 使用or,or两边字段必需都有索引,否则一方有索引,也会导致索引失效。
  9. 对字符类型的字段进行了数字操作,类型不匹配也会失效。
  10. 多条插入数据,应使用批量插入,在mybatis框架中还可以通过fetchsize参数来优化。
  11. order排序对有索引的字段进行排序。没有索引会查找数据后,对数据排序,有索引查找的时候就已经通过索引排序了。
  12. count(*) > count(1) > count(字段)

EXPLAIN分析

了解:
EXPLAIN用来查看优化器的执行过程,可以更好的了解sql执行的过程,根据分析最后优化sql。参考链接:https://cloud.tencent.com/developer/article/1485767
https://blog.csdn.net/wang5701071/article/details/117782061
优化:
explain select * from teacher;
在这里插入图片描述
列释义:

  1. id:id不同,id越大,优先级越高,越先执行;id相同,从上到下执行。
  2. select_type:
    -SIMPLE:简单查询,没有子表,联表UNION等操作。
    -PRIMARY:对于有复杂的成份,子表等,最外层表的标识。
    -SUBQUERY:不在from中的,在where后出现的子表操作,该子表的标识。
    -DERIVED:from后的子表,也称派生表。
    -UNION:第一个表之后的使用UNION的表的标识。
    -UNION RESULT:UNION之后的结果表标识。
  3. table:表名。
  4. type:效率排序从高到低 const,system>eq_ref>>ref>range>index>all
    -const:只查出一条数据,并且查询字段是主键primary或者unique唯一索引的。
    -system:只有一条数据的系统表,或派生表只有一条数据。
    -eq_ref:唯一性的索引,此表的每条数据都只有一条数据能被关联找出,不能多,也不能为0。
    -ref:对每个索引键的查询能查出多个或0个。
    -range:带有范围的查询。
    -index:对带有索引的字段全表查询,如果select后带有没有索引的字段则是ALL。
    -all:不走索引,全表扫描。如果有非聚集索引字段,可以建立联合索引,避免回表。
  5. possible_keys:可能用到的索引键
  6. key:实际用到的索引键
  7. key_len:索引键长度,主要用来判断是否使用了联合索引。
    -字符型:
    varchr(10)变长字段且允许NULL = 10 * ( character set: utf8=3,gbk=2,latin1=1)+1(NULL)+2(变长字段)
    varchr(10)变长字段且不允许NULL = 10 *( character set:utf8=3,gbk=2,latin1=1)+2(变长字段)
    char(10)固定字段且允许NULL = 10 * ( character set:utf8=3,gbk=2,latin1=1)+1(NULL)
    char(10)固定字段且不允许NULL = 10 * ( character set:utf8=3,gbk=2,latin1=1)
    -数值类型 tinyint:1字节 smallint:2字节 int:4字节 bigint:8字节  
    -时间类型  date:3字节 timestamp:4字节 datetime:8字节
  8. ref:列出where后是通过常量(const),还是某个表的某个字段(如果是join)来联接表
  9. rows:预估查询出的数据行数。
  10. extra:
    -Using index:所需要的数据,只需要在索引即可全部获得,而不需要再到表中取数据
    -Using where:如果我们不是读取表的所有数据,或者不是仅仅通过索引就可以获取所有需要的数据,则会出现Using where信息。
    -Using index和Using where前面已经有例子,当出现索引覆盖时,会显示Using index,性能得到了提升,出现Using temporary和Using filesort说明性能损耗比较大
    -Using temporary:当MySQL某些操作中必须使用临时表时,在Extra信息中就会出现Using temporary。主要常见于GROUP BY和ORDER BY等操作中
    -Using filesort:这意味着MySQL会对结果使用一个外部索引排序,而不是按索引次序从表里读取行

性能分析

参考链接:https://blog.csdn.net/wang5701071/article/details/123920789
1.sql执行次数分析: show global status like ‘Com_______’
2.慢日志查询:show variables like ‘%slow_query_log%’
3.开启慢日志:set global slow_query_log=1
4.设置慢日志过滤时间: set global long_query_time=2
5.profile是否可用:SELECT @@profiling
6.开启profile:SET profiling = 1
7.查询近期的sql语句执行时间:show profiles;
8.具体某一个sql的执行时间:shwo profile for query id; id是show profiles里面的。
9.查看cpu或者其他参数的分析:show profiles cpu for query xx;

猜你喜欢

转载自blog.csdn.net/qq_42878634/article/details/126280593