MySQL-性能分析与索引
MySQL执行流程
MySQL 缓存
-
将sql语句 和 对应的结果集进行存储 存储结构类似于map(sql 作为key的校验比较严格,即使是相同的sql但是格式不一样(例如其中一个包含空格)也会被视为不同的key)
-
mysql 缓存命中比较低,在8.0中已经删除了缓存,低版本中也可以选择关闭
MySQL索引结构
B+数结构
非叶子阶段不存储数据页,这样非叶子节点可以存储更多的数据,使树的高度降低
叶子节点是双链表结构,当使用>或者< 查找时可以通过直接遍历双线表,提高查找效率
主键索引叶子节点存放数据记录,非主键索引叶子节点会存放主键id,和建立索引列的值
MySQL性能分析
查看执行次数
show global status like 'Com_______' ;
慢查询日志
(默认没有开启,需要修改配置文件)
慢查询日志可以查看所有执行时间超过指定参数(默认10s)的所有sql语句的日志
样例:
profile命令
查看是否支持
select @@have_profiling;
查看是够开启
select @@profiling;
开启命令
set profiling =1 ;
使用案例
show profiles ;
show profile for query 157 ;
explain
id:查询顺序,id值越大越先执行 ,id相同执行顺序从上到下
select_type:查询类型
type:表示连接类型
system > const > eq_ref > ref > range > index > all
possible_key: 可能使用的索引
key:实际用到的索引
key_length:索引中使用的字节数,该值为索引字段最大可能长度,不是实际使用长度(越短越好)
filtered:返回结果行数占读取行数的百分比(越大越好)
最左匹配原则
建立联合索引,使用where条件查询时必须含联合索引中序号最高的列,否则不会使用索引
例如:对a,b,c三个字段建立联合索引 字段序号a>b>c ,查询语句where 条件必须含有a,否则不使用索引。如果跳过了某一列,那么索引讲部分失效。(写sql时查询条件顺序无所谓,mysql会自动优化,可以通过索引长度字段来判断是否使用全部索引)
如果出现查询范围>,<时,范围查询右侧的列索引失效
索引失效的场景
-
查询条件使用运算符
-
字符串查询没有使用单引号
-
头部模糊匹配(%*)
-
or前条件有索引,后面的列没有索引(可使用union)
-
使用索引比全表还慢(is null 和 is not null 走不走索引取决于表中数据分布)
sql提示
当查询条件有联合索引和单列索引可以用时 可以指定sql使用那一列索引
select * from user use index (idx_user_no) where no = 1;
select * from user ignore index (idx_user_no) where no = 1;
select * from user force index (idx_user_no) where no = 1;
回表查询
extra 列 : using index condition
(避免使用select *)
前缀索引
对于过长的字符串列 可截取前几个字符来建立索引,减少索引占用的空间