>##exists与in
``` sql
select * from A where exists (select * from B where A.id=B.id);
```
A 表为外表 exists执行外表循环,所以应该是小表,B表可以是大表走索引
```
select * from A where A.id in (select id from B);
```
in 查询会把A表B表建立hash连接,先查询B表,在对A表进行匹配,这时候A表的匹配时可以用到索引的,A表适合大表的情况,B表可大可小,都可走索引
综上,在B表都可以走索引的情况下,in更优
>##索引
- `high`where 列 order by 列,需要建立索引
- `low` 当列为null的情况,mysql建立索引复杂度提高,一定程度上影响性能
- `high`复合索引情况下,遵循最左原则,例如 (a,b,c) 匹配a,b,c /a,b/a,c/a 以上顺序随意
- 避免对拥有大量重复值的列建立索引,很多情况下会使得检索反而变慢,先扫描整个非聚集索引表
- 尽量使用 select name,age,sex from table 替代 select * from table
- 引擎放弃索引而进行全表扫描的情况
- innodb 引擎 or 条件查询(多表) select A.* ,B.* from A,B where A.id=B.id and (A.name='zs' or B.name='ww')
改成union all 的写法
- where name like '%zs%' 需要改成 where name like 'zs%'
- where age/2=20 `=`号左侧避免进行计算
- InnoDB的行锁是针对索引加的锁,不是针对记录加的锁。并且该索引不能失效,否则都会从行锁升级为表锁
- update table where id=1 (id必须得加索引,否则会升级成表锁)
- where 1=1 要注意会使得索引失效,对性能有要求的地方禁用
> 性能
ALL--index--range--ref--eq_ref--const,system--NULL
- ALL: 扫描全表
- index: 扫描全部索引树
- range: 扫描部分索引,索引范围扫描,对索引的扫描开始于某一点,返回匹配值域的行,常见于between、等的查询
- ref: 使用非唯一索引或非唯一索引前缀进行的查找
(eq_ref和const的区别:)
- eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描
- const, system: 单表中最多有一个匹配行,查询起来非常迅速,例如根据主键或唯一索引查询。system是const类型的特例,当查询的表只有一行的情况下, 使用system。
- NULL: 不用访问表或者索引,直接就能得到结果,如select 1 from test where 1
PRIMARY, INDEX, UNIQUE 这3种是一类
PRIMARY 主键。 就是 唯一 且 不能为空。
INDEX 索引,普通的
UNIQUE 唯一索引。 不允许有重复。
FULLTEXT 是全文索引,用于在一篇文章中,检索文本信息的。 SPATIAL 空间索引