数据库相关知识点
1、Mysql常见两种存储引擎MyISAM和InnoDB的区别
MyISAM特点:
- 不支持行锁(MyISAM只有表锁),读取时对需要读到的所有表加锁,写入时则对表加排他锁
- 不支持事务
- 不支持外键
- 不支持崩溃后的安全恢复
- 在表有读取查询的同时,支持往表中插入新纪录
- 支持BLOB和TEXT的前500个字符索引,支持全文索引
- 支持延迟更新索引,极大地提升了读写性能
- 对于不会进行修改的表,支持压缩表,极大地减少了磁盘空间的占用
- 表锁:每次操作锁住整张表,开销小,加锁快;不会出现死锁;锁定粒度大,发生冲突的概率最高,并发度最低
- 行级锁:每次操作锁住一行数据,开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高
- 支持行锁,采用MVCC来支持高并发,有可能死锁
- 支持事务
- 支持外键
- 支持崩溃后的安全恢复
- 不支持全文索引
2、索引的优缺点
优点:
- 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性
- 可以大大加快数据的检索速度,这也是创建索引的最主要原因
- 可以加快表和表之间的连接,特别是在实现数据的参考完整性方面有特别的意义
- 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间
- 通过使用索引,可以在查询过程中,使用优化隐藏器,提高系统的性能
- 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加
- 索引需要占用物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大
- 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度
3、索引的创建方式
- 在执行CREATE TABLE时创建索引
- 使用ALTER TABLE命令去增加索引,可以用来创建普通索引、UNIQUE索引或PRIMARY KEY索引 ALTER TABLE table_name ADD INDEX/UNIQUE/PRIMARY KEY/FULLTEXT index_name (column_list)
- 使用CREATE INDEX命令创建索引 CREATE INDEX/UNIQUE INDEX index_name ON table_name(column_list)
4、索引的删除
- 使用ALTER TABLE语句实现 ALTER TABLE [table_name] DROP INDEX [index_name]
- 使用DROP INDEX 【index_name】 ON 【table_name】
5、索引分类
- 普通索引
- 唯一索引,与普通索引类似,不同的是,MySQL数据库索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一
- 主键索引,特殊的索引,不允许有空值,一般是在建表的时候同时创建主键索引
- 全文索引(FULLTEXT),全文检索是对大数据文本进行索引,在建立的索引中对要查找的单词进行搜索,定位哪些文本数据包括要搜索的单词。因此,全文检索的全部工作就是建立索引和在索引中搜索定位,所有的工作都是围绕这两个来进行的
6、单列索引与组合索引(多列索引)
MySQL能在多列上创建索引,多个单列索引与单个多列索引的查询效果不同,因为执行查询时,MySQL只能使用一个索引,会从多个单列索引中选择一个限制最为严格(获得结果集记录数最少)的索引
适用场景:
- 全字段匹配
- 匹配部分最左前缀
- 匹配第一列
- 匹配第一列范围查询(可用like a%,但不能用like %b)
- 精确匹配某一列和和范围匹配另外一列
7、索引设计优化
(1)最左匹配原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a=1 and b=2 and c>3 and d=4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的。如果建立(a,b,d,c)的索引则都可以用到,abd的顺序可以任意调整
(2)=和in可以乱序。a=1 and b=2 and c=3建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮我们优化成索引可以识别的形式
(3)尽量选择区分度高的列作为索引,表示字段不重复的比例高
(4)尽量扩展索引,不要新建索引
(5)定义有外键的数据列一定要建立索引
(6)对于定义为text、image和bit的数据类型的列不要建立索引
(7)对于经常存取的列避免建立索引
8、数据库优化
(1)应尽量避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描。最好不要给数据库留null,尽可能使用not null填充数据库
(2)应尽量避免在where子句中使用!= 或<>操作符,否则引擎将放弃使用索引而进行全表扫描
(3)应尽量避免在where子句中使用or来连接条件,如果一个字段有索引另一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描
(4)in和not in也要慎用,否则会导致全表扫描;对于连续的数值,能用between就不要用in了
(5)应尽量避免在where子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描
(6)应尽量避免在where子句中对字段进行函数操作