索引
Innodb(没特殊需求,默认使用innodb)
1. 支持事务
2. 聚族索引(必须有主键,不指定则会自动生成一个默认的费,数据文件在主键索引叶子节点上)
3. 行锁(并发读写性能好)
4. 不记录总行数(count(*)会扫描全表)
5. 崩溃安全恢复支持(redo log、binlog配合)
Myisam
1. 不支持事务
2. 非聚族索引(索引、数据分开存储)
3. 表锁(整改锁整个表)
4. 记录总行数
默认索引引擎使用innodb
索引类型
1. 主键索引:innodb必须有一个主键,没有不指定则会自动生成一个默认的。数据文件在主键索引叶子节点上
2. 普通索引:索引上存储的是主键,所以使用查询时,先通过索引查询出主键,然后取主键索引上取对应数据,这个过程称作 回表。所以主键索尽量小,其他索引都会存储主键索引
3. 前缀索引: 使用字符串字段做索引,当字符串比较长,为了节省存储空间可以截取字符串前段做索引,截取长度可以根据测试的区分度定。(比如邮箱字段)
4. 唯一索引: 可保证唯一性,其他基本跟普通索引一致。(插入、修改操作需要先查询是否已存在,所以性能会比普通索引底一点)
5. 复合索引: 多个字段共同建一个索引。 (最左原则)
需要关注的点
1. 区分度:区分度越高,索引效果越好
2. 索引是有代价的,性能:数据操作都需要维护索引,存储:每个索引都是单独存储的,极端情况有索引比数据大的情况。
3. 最左原则: 字符串、复合索引都会用到。
比如 abcde 是一个索引字段的值,使用 like abc% 来模糊查询时是可以利用到索引的,like %abc 、bc% 则不行。
a,b,c 建立复合索引 使用 a,b,c、a,b、a,都可以利用索引 b、b,c这种则不行。a,c 则相当是a
4. 覆盖索引:避免回表的一种优化方式,a,b,c 建立复合索引 select a,b,c forn t where a=? And b=?,像这种需要返回的字段索引中都存在,则直接返回,不用回表。
5. 多个索引只会使用一个
6. order by :索引字段能优化排序,因为索引本身是有序的。前提是使用了这个索引,索引是有代价的,需要根据实际情况取舍。
用不上索引的话,尽量让数据库使用内存排序。避免使用文件排序, 这取决于排序所需的内存和参数 sort_buffer_size
7. group by: 也可以利用索引,直接累计数量就好,省去了分组后排序的操作
8. join: 使用join查询,被驱动表的关联字段一定需要添加索引,不然会全表扫描(假如表a是n行,表b是M行,扫描数量就是n*m),使用数量少的表做驱动表(主表),数量少是经过指定条件筛选后的数量。
如果被驱动表不适合添加索引,可以使用 where in 关联字段 来代替join,然后在程序中循环处理。
9. 类型转换:
比如 索引字段a是字符串,where条件使用数组 a=123查询,会字符串转数字然后对比,导致索引失效,全表扫描。
使用内置函数处理也会导致全表扫描
事务
1. 避免使用大事务,尽量分割成小事务。大事务往往涉及多个表中多个数据,大量的行锁会导致其他修改相同数据的事务处于等待锁状态,降低数据库的性能。而且很容易发生死锁。
2. 避免 批量删除,原因同上,会大量加行锁,导致性能问题
3. (热点)数据的增改操作 在事务中尽量往后放,因为事务加写锁是执行到语句的时候才加锁,往后放会会减少锁冲突,提高性能。