知识点:
- 就算一开始不创建id作为索引 mysql也会自动在你的字段内寻找唯一标识 如果唯一标识不存在就使用行号作为索引
- 聚簇索引 B+树结构 自上而下分层 id和数据在一块
- 非聚簇索引 索引的字段和id绑定 得到所需要的id后的回表查询
- 为什么B+树更合适做索引 B-树上是ID+数据 数据库IO读取是以page来读取的 一次读取4K 如果像B-树上 id和数据绑定在一层上 那么一层能存取的数据量就会变少B+树 一个page下的id int类型只占4个字节 可以存储的更多 它的叶子节点才会有 id+数据
- 但是不能盲目添加索引 索引也是占有数据量的
- 越低IO能解决相同事情的程序 更优
- 不到百万级数据量不要轻易建索引
小知识:
- 以%开头的like走不了索引 但是%结尾的可以走索引
- 如果查询超过全表的百分之三十的数据量 mysql默认会走全表扫描(走索引会一直回表 可能比全表扫描还慢)
- 不用在列上做过多的运算 会导致索引失效
什么时候没必要用
1.唯一性差;
2.频繁更新的字段不用(更新索引消耗);
3.where中不用的字段;
4.索引使用<>时,效果一般;
Explain关键字
id:select查询的序列号
select_type:select查询的类型,主要是区别普通查询和联合查询、子查询之类的复杂查询
table: 输出的行所引用的表
type:
联合查询所使用的类型,type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:
system > const > eq_ref > ref >fulltext > ref_or_null > index_merge > unique_subquery >index_subquery > range > index > ALL
一般来说,得保证查询至少达到range级别,最好能达到ref。
type=const表示通过索引一次就找到了;
type=all,表示为全表扫描;
type=ref,因为这时认为是多个匹配行,在联合查询中,一般为REF;
key:
显示MySQL实际决定使用的键。如果没有索引被选择,键是NULL。
key=primary的话,表示使用了主键;
key=null表示没用到索引。
possible_keys:
指出MySQL能使用哪个索引在该表中找到行。如果是空的,没有相关的索引。这时要提高性能,可通过检验WHERE子句,看是否引用某些字段,或者检查字段不是适合索引。
key_len:
显示MySQL决定使用的键长度。如果键是NULL,长度就是NULL。文档提示特别注意这个值可以得出一个多重主键里mysql实际使用了哪一部分。
ref:
显示哪个字段或常数与key一起被使用。
rows:
这个数表示mysql要遍历多少数据才能找到,在innodb上是不准确的。
Extra:
如果是Only index,这意味着信息只用索引树中的信息检索出的,这比扫描整个表要快。
如果是where used,就是使用上了where限制。
如果是impossible where 表示用不着where,一般就是没查出来啥。
SQL语句优化:
1.当有人问起你mysql语句如何优化的时候 使用explain关键字对写的mysql语句进行查询语句执行的性能 type 最好不要出现全表扫描的情况 要适当添加索引来优化查找的性能 rows也是性能指标之一 当type为const的时候 row 只会唯一 通过索引方式直接定值查找了一条数据 性能是除了Null以外最高的(Null 不执行查询)
2.typeorm的语句优化:typeorm 有生成原始语句的方式 如果出现了All的情况下 尽快修改 当数据到达一定量 查询就会耗时非常长 提高查询效率 当然对应的代价就是索引也会占硬盘容量 符合计算机 空间换取时间
3.少用子查询 多用左连接 少用 *
4.使用小事务 不用大事务 表锁升级行锁
5.slow log 慢查询日志 记载了查询速度慢的操作 可以去查看 并且去优化对应的操作