>##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 空间索引