数据库 详解explain 性能优化

  • Post author:
  • Post category:其他


1、explain

explain能够查看sql语句的执行计划,查看是否使用了索引,有没有做全表扫描,这些信息对于我们sql的优化有着很大作用

示例

由上图可知对执行的sql添加explain会返回以下数据

id:选择标识符

select_type:标识查询的类型

table:输出结果集的表

paritions:匹配的分区

type:表示连接的类型

possible_keys:表示查询的时候,可能使用到的索引

key:表示实际使用到的索引

key_len:索引字段的长度

ref:列与索引的比较

rows:扫描出的行数

filtered:按照表条件过滤的行百分比

extra:执行情况的描述和说明

1.1 id

select标识符,即sql执行的查询序列号

1、id相同时,执行顺序从上向下

2、如果是子查询,id的序号会递增。id值越大,越先被执行

1.2 select_type

表示查询中每个select子句的类型

(1) SIMPLE(简单SELECT,不使用UNION或子查询等)

(2) PRIMARY(子查询中最外层查询,查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)

(3) UNION(UNION中的第二个或后面的SELECT语句)

(4) DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)

(5) UNION RESULT(UNION的结果,union语句中第二个select开始后面所有select)

(6) SUBQUERY(子查询中的第一个SELECT,结果不依赖于外部查询)

(7) DEPENDENT SUBQUERY(子查询中的第一个SELECT,依赖于外部查询)

(8) DERIVED(派生表的SELECT, FROM子句的子查询)

(9) UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)

1.3 table

显示这一步所访问的数据库中表名称

1.4 type

查找数据的访问方式

常用的类型有:

ALL、index、range、 ref、eq_ref、const、system、


NULL(从左到右,性能从差到好)


ALL:将全表扫描,找到所需要的行


index:只遍历索引数


range:只检索给定范围的行


ref:表示上述表的连接匹配条件

1.5 possible_keys

表示查询涉及到的字段上若存在索引,则改索引被列出,但不一定真实的使用这个索引

1.6 key

表示实际使用的索引,这个索引必然包含在possible_keys中

1.7 key_length

表示索引中使用的字节数

1.8 ref

列与索引的比较,表示上述表的连接匹配条件,即哪些列或常量用于查找索引列的值

1.9 rows

估算出的结果集行数

1.10 Extra

包含mysql解决查询的详细信息


2、从哪几个维度优化数据库性能的问题

1、数据库配置,客户端连接服务端,并发的情况下,数据库的连接不够

  • 服务端设置最大的连接数 show variables like ‘max_connections’ ,修改连接数的命令:set GLOBAL max_connections=100; 或者直接修改配置文件
  • 客户端使用连接池,应用池化技术不需要新建一个连接,MyBatis自带一个连接池,或者阿里的druid.这里注意并不是连接池的连接数越大越好,相反连接数越大会影响性能,因为这根cpu的性能有关系,当维护的线程数越多,CPU处理不过来

2、架构层面的优化

  • 引入一个独立运行的缓存中间件,分担数据库的压力;
  • 主从分离进行读写分离
  • 水平分库分表

3、存储引擎的选择与表结构设计

  • MyISAM

不支持事务:对事务要求的业务场景不能使用

表级锁定 :锁机制是表级索引,降低了其并发的性能

读写互相阻塞:不仅会在写入的时候阻塞读取,读取的时候也会阻塞写入,但读本身并不会阻塞另外的读


使用场景:

  1. 不需要事务支持的业务
  2. 并发相对较低
  3. 数据修改相对较少,以读为主
  4. 数据一致性要求不是非常高
  • InnoDB

具有事务支持:支持4个事务的隔离级别

行级锁定,全表扫描仍然是表锁

读写阻塞与事务的隔离级别有关


使用场景:

  1. 需要事务支持
  2. 数据更新较为频繁的场景
  3. 数据一致性要求较高
  • 表结构设计:选择合理的存储引擎,字段设计考虑大小

4、SQL,索引优化

a、返回数据避免*,需要啥字段,返回啥字段

b、SQL语句中IN包含的值不应太多,对于连续查询的能用between就不要用in

c、当只需要一条数据的时候,使用limit

d、如果排序字段没有用到索引,就尽量少排序

e、如果限制条件中其他字段没有用到索引,少用or

f、不建议使用like’%name’ 或者 like ‘%name%’,这样查询会导致索引失效从而进行全表扫描,如果想要的如此查询的话,建立全文索引

创建全文索引:alter table 表名 add fulltext index ‘索引名’ (字段1,字段2)

使用全文索引:select id ,fnum,ddst from 表 where match(user_name) against(‘name’ in boolean mode);

g:范围查询或者一些函数计算都会导致索引失效

h:关联查询尽量使用inner join,避免left join,因为前者会自动选择数据小的表作为驱动表,利用小表驱动大表

i:合理的使用创建索引

5、业务层次的优化

  • 充值送奖金的业务,银行卡支付性能会低于充值的支付
  • 限流,MQ



版权声明:本文为weixin_42558742原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。