一、拿到SQL之后,用执行计划查看参数。
explain select 1 from `d_ec_hyx`.`t_advertiser_info` where 1 = 1 and f_corp_id = 15930142 and f_type in (1, 4) and f_refund_status = 1 limit 1
二、 执行计划 ID。
1、id 相同,执行顺序从上往下;
2、id 不同,如果是子查询,id 的序号会递增,id 值越大优先级越高,越先被执行;
3、id 有相同的又有不同的 (混合式的),即两种情况都存在,id 如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id 值越大,优先级越高,越先执行;
4、id 为 null 的最后执行;比如 union 查询可能 id 为 null;
三、执行计划 select_type。查询的类型,主要是用于区分普通查询、联合查询、子查询等;
SIMPLE:简单的 select 查询,查询中不包含子查询或者 union;
PRIMARY:查询中包含子部分,最外层查询则被标记为 primary;
SUBQUERY:SUBQUERY 表示在 select 或 where 列表中包含了子查询;
MATERIALIZED:表示 where 后面 in 条件的子查询;
UNION:若第二个 select 出现在 union 之后,则被标记为 union;
UNION RESULT:从 union 表获取结果的 select;
四、执行计划 table。
查询涉及到的表,直接显示表名或者表的别名;
<unionM,N> ID 为 M 和 N 查询结果进行 union 后产生的结果;
<subqueryN> ID 为 N 进行子查询产生的结果;
五、执行计划 partitions。
匹配的分区信息,如果查询基于分区表,将会显示访问的是哪个区;
表分区:表分区是将一大表,根据条件分割成若干个小表,mysql 5.1 开始支持数据表分区,比如:某用户表的记录超过了 2 万条,那么就可以根据 id 将表分区,也可以根据时间分区,当然也可根据其他的条件分;
比如:
partition BY RANGE (uid) (
partition p0 VALUES LESS THAN (10000),
partition p1 VALUES LESS THAN (20000)
);
按照这种分区方案,uid 小于 10000 的所有行被保存在分区 P0 中,uid 在 10000 到 20000 的保存在 P1 中,依次类推;
六、执行计划 type【需要关注】
访问类型,sql 查询优化中一个很重要的指标,结果值从好到坏依次是:
system > const > eq_ref > ref > range > index > ALL
system:const 类型的特例,基本不会出现,可以忽略不计;
const: 表示通过索引一次就找到了,const 用于比较 primary key 或者 unique 索引,可以说是性能最好的,1;
eq_ref:唯一索引扫描,对于每个索引键,表中只有一条记录与之匹配,常见于主键 或 唯一索引扫描,性能次之,2;
ref:非唯一性索引扫描,返回匹配某个单独值的所有行,本质是也是一种索引访问,性能次之,3;
range:只检索给定范围的行,使用一个索引来选择行,性能次之,4;优化最坏的情况要达到这个级别 range;
index:Full Index Scan,索引全表扫描,把索引从头到尾扫描一遍;
ALL:Full Table Scan,扫描全表以找到匹配的行;
七、执行计划 possible_keys。查询过程中有可能用到的索引;
八、执行计划 key【需要关注】
实际使用的索引,如果为 NULL,则表示没有使用索引;
九、执行计划 key_len。
实际使用到的索引长度
十、执行计划 ref。
当使用索引列等值查询时,与索引列进行等值匹配的对象信息;
十一、执行计划 rows 扫描行数【需要关注】
根据表统计信息或索引选用情况,大致估算出找到所需记录所需要读取的行数;
十二、执行计划 filtered。
表示返回结果的行数占需读取行数的百分比,filtered 的值越大越好,100 是最好的情况;
十三、执行计划 Extra。【需要关注】
十分重要的额外信息,这些额外信息有:
1、Using filesort:
mysql 对数据使用一个外部的文件内容进行了排序,而不是按照表内的索引进行排序读取;
2、Using temporary:
使用临时表保存中间结果,也就是说 mysql 在对查询结果排序时使用了临时表,比如在 order by 或 group by;
中间 MySql 处理过程需要多处理一个临时表,一般这种情况是需要优化处理的。
优化处理一般使用索引优化;
3、Using index:
表示相应的 select 操作中使用了覆盖索引(Covering Index),避免了访问表的数据行,效率高 (不去回表操作);
4、Using where:
使用了 where 过滤条件;
5、select tables optimized away:
基于索引优化 MIN/MAX 操作或者 MyISAM 存储引擎优化 COUNT (*) 操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即可完成优化;
6. 优化建议
1. 所有表必须使用 Innodb 存储引擎
没有特殊要求(即 Innodb 无法满足的功能如:列存储,存储空间数据等)的情况下,所有表必须使用 Innodb 存储引擎(MySQL5.5 之前默认使用 Myisam,5.6 以后默认的为 Innodb)。
Innodb 支持事务,支持行级锁,更好的恢复性,高并发下性能更好。
2. 数据库和表的字符集统一使用 UTF8
兼容性更好,统一字符集可以避免由于字符集转换产生的乱码,不同的字符集进行比较前需要进行转换会造成索引失效,如果数据库中有存储 emoji 表情的需要,字符集需要采用 utf8mb4 字符集。
3. 所有表和字段都需要添加注释
使用 comment 从句添加表和列的备注,从一开始就进行数据字典的维护
4. 尽量控制单表数据量的大小,建议控制在 500 万以内。
500 万并不是 MySQL 数据库的限制,过大会造成修改表结构,备份,恢复都会有很大的问题。
可以用历史数据归档(应用于日志数据),分库分表(应用于业务数据)等手段来控制数据量大小
5. 谨慎使用 MySQL 分区表
分区表在物理上表现为多个文件,在逻辑上表现为一个表;
谨慎选择分区键,跨分区查询效率可能更低;
建议采用物理分表的方式管理大数据。
6. 尽量做到冷热数据分离,减小表的宽度
MySQL 限制每个表最多存储 4096 列,并且每一行数据的大小不能超过 65535 字节。
减少磁盘 IO, 保证热数据的内存缓存命中率(表越宽,把表装载进内存缓冲池时所占用的内存也就越大,也会消耗更多的 IO);
更有效的利用缓存,避免读入无用的冷数据;
经常一起使用的列放到一个表中(避免更多的关联操作)。
7. 禁止在表中建立预留字段
预留字段的命名很难做到见名识义。
预留字段无法确认存储的数据类型,所以无法选择合适的类型。
对预留字段类型的修改,会对表进行锁定。
8. 禁止在数据库中存储图片,文件等大的二进制数据
通常文件很大,会短时间内造成数据量快速增长,数据库进行数据库读取时,通常会进行大量的随机 IO 操作,文件很大时,IO 操作很耗时。
通常存储于文件服务器,数据库只存储文件地址信息
9. 禁止在线上做数据库压力测试
10. 禁止从开发环境,测试环境直接连接生产环境数据库
标签:语句,分区,SQL,查询,索引,MySQL,执行,id,select From: https://www.cnblogs.com/chuhecc/p/17715673.html