目录
连接查询
MySQL常用函数汇总
SQL Select 语句的执行顺序
聚集索引和非聚集索引的区别
- 聚集索引:包含主键和非主键数据以及索引
- 非聚集索引:只包含主键和索引,当没有实现索引覆盖时会进行回表,走聚集索引
数据库三范式
第一范式
1NF 原子性,列或者字段不能再分,要求属性具有原子性,不可再分解;第二范式
2NF 唯一标识。即每个表只描述一种实体,每个记录都有唯一标识,不存在部分依赖关系。 主要是解决行的冗余。- 每个表必须有一个主键
- 非主键字段要完全依赖于主键
第三范式
3NF 直接性,非主键字段不依赖于其它非主键字段, 主要是解决列的冗余.
MyISAM 存储引擎 与 InnoDB 引擎区别
事务支持:MyISAM 不支持事务处理,而 InnoDB 支持事务处理,可以通过使用事务来确保数据的完整性和一致性。
锁定机制(锁的粒度):MyISAM 表级锁在执行 SELECT 操作时会对 表 进行读锁定,而执行 INSERT、UPDATE 或 DELETE 操作时会对 表 进行写锁定,因此在写操作执行时,读操作会被阻塞。而 InnoDB 支持行级锁,不会对整个表进行锁定,可以减少锁定冲突和死锁的发生。
外键支持:MyISAM 不支持外键约束,而 InnoDB 支持外键约束,可以通过外键约 束来保证数据的引用完整性
并发性能:在并发性能方面,InnoDB 要优于 MyISAM。由于 InnoDB 支持行级锁定 和 事务处理,因此在高并发情况下,InnoDB 的并发性能更高。
因此,在设计数据库时,需要考虑具体情况选择适合的 存储引擎。
- 如果需要支持事务处理 和 外键约束,以及具有更好的并发性能,则应选择 InnoDB。
- 如果只是进行简单的读写操作,并且需要更快的查询速度,则可以选择 MyISAM。
索引
索引存储在 内存 中,为服务器存储引擎为了快速找到记录的一种数据结构。
索引的主要作用是 加快数据查找速度,提高数据库的性能。 空间换时间
索引的优缺点
优点:加快查询效率
唯一性索引:保证数据库表中每一行数据的唯一性
加速查询:减少数据扫描的行数,从而提高查询速度。
加速排序和分组:索引可以帮助优化 ORDER BY 和 GROUP BY 操作。
缺点:
- 占用空间:索引会增加磁盘空间的使用。
- 影响写性能:插入、删除、更新操作需要维护索引,可能会导致性能下降。
索引的分类
普通索引:加速数据的检索,允许重复值。
唯一索引:确保列中的所有值唯一,加速查询。但允许有空值。
主键索引:特殊的唯一索引,用于唯一标识数据表中的某一条记录,不允许有空值。
联合索引(又叫复合索引):由多个列组成的索引,提升多列查询的效率。遵循靠左原则。
最左前缀匹配原则:即在使用复合索引时,查询条件必须包含索引中最左边的列才能触发索引的使用。如果查询条件没有包含最左边的列,则索引无法生效。
使用场景:
- 登录时,手机号+密码
- 商品表中,类型+状态
- 订单表中,订单号+用户Id
全文索引:用于快速全文搜索。不过一般使用ElasticSearch做全文索引(搜索引擎库)。
索引结构
Mysql 目前提供了以下 4 种索引:
- B+Tree 索引: 最常见的索引类型, 大部分索引都支持 B+树索引.
- Hash 索引: 只有 Memory 引擎支持, 使用场景简单.
- R-Tree 索引(空间索引): 空间索引是 MyISAM 引擎的一个特殊索引类型, 主要地理空间数据
- S-Full-text(全文索引): 主要用于全文索引, InnoDB 从 Mysql5.6 版本开始支持全文索引.
B树与B+树的区别
- 存储数据的位置:
- B树: 数据既存储在所有节点中(叶子节点和非叶子节点都有数据)
- B+树: 所有的数据记录都存储在叶子节点中,非叶子节点仅包含索引信息。叶子节点包含了完整的数据和索引键。
- 叶子节点之间的链接:
- B树: 叶子节点之间没有链接。
- B+树: 叶子节点之间通过指针相互链接,形成一个 链表 或 循环链表,这使得范围查询和遍历变得高效。
补充:动画演示数据结构
索引失效的几种情况
范围条件查询
当查询到的记录大于总记录数30%时,就不再使用索引,直接会扫描全表索引列上操作(使用函数、计算等)导致索引失效
字符串不加引号, 造成索引失效
OR 关键字连接:OR关键字两边的字段必须都要有索引,任一个字段没索引就会进行全表扫描
使用
!=
导致索引失效like以通配符开头
('%abc...')
导致索引失效排序列包含不同索引的列
数据库锁
行锁和表锁
主要是针对锁粒度划分的,一般分为:行锁、表锁、库锁行锁:访问数据库的时候,锁定整个行数据, 防止并发错误。
表锁:访问数据库的时候,锁定整个表数据,防止并发错误。
行锁 和 表锁 的区别:
- 行锁:
开销大,加锁慢,会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高 - 表锁:
开销小,加锁快,不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低
悲观锁和乐观锁
- 悲观锁:每次去拿数据的时候都认为会进行修改,所有每次在拿数据的时候都会上锁.
- 乐观锁:每次去拿数据的时候都认为不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间有没有更新这个数据,使用版本号机制,如果版本号不支持舍弃这次操作,并且设置 重试机制,乐观锁适用于多读的应用类型 ,这样可以提高吞吐量 。
MySql 优化
SQL慢查询优化
- 定位执行效率慢的 sql 语句
- EXPLAIN:可以帮助分析查询计划,查看索引是否被使用。
- 慢查询日志:开启 MySQL 的慢查询日志,分析执行时间较长的查询,优化相关索引。
- 拓展:
- 使用
xxl-job
查询慢日志 - 通过
elk
监控自己项目的日志 - 使用
skyWalking
查看哪个接口比较慢
- 使用
Sql 语句优化
多表连接的字段上需要建立索引,这样可以极大提高表连接的效率.
避免在索引列上使用计算
避免在索引列上使用
IS NULL
和IS NOT NULL
对查询进行优化,应尽量避免全表扫描,首先应考虑在
where
及order by
涉及的列上 建立索引。应尽量避免在 where 子句中对字段进行表达式操作和
null
值判断,这将导致引擎放弃使用索引而进行全表扫描排序时,尽量同时用升序或同时用降序.
分组时默认会进行排序,额外的排序会降低效率. 如果不需要排序可以禁止, 使用
order by null
禁用默认排序.尽量避免子查询, 可以将子查询优化为 join 多表连接查询.
避免使用
SELECT *
列表数据不要拿全表,要使用LIMIT来分页,每页数量也不要太大,当只要一行数据时使用
LIMIT 1
索引优化
对查询频繁, 且数据量比较大的表, 建立索引.
遵循最左前缀匹配原则,合理设计复合索引。
复合索引命名规则: index _ 表名 _ 列名 1 _ 列名 2 _ 列名 3
使用覆盖索引,减少回表查询。
定期检查并删除冗余或重复的索引。
利用唯一索引提高查询效率, 区分度越高, 使用索引的效率越高.
使用短索引, 提高索引访问时的 I/O 效率, 从而提升 Mysql 查询效率.
表优化
保留冗余字段:避免表之间的连接过于频繁
增加派生列。派生列是由表中的其它多个列的计算所得,增加派生列可以减少统计运算 这也就是反第三范式。
分割表:垂直拆分和水平拆分。
- 水平切分:将记录散列到不同的表中,各表的结构完全相同,每次从分表中查询, 提高效率。
- 垂直切分:将表中大字段单独拆分到另外一张表, 形成一对一的关系。
字段设计
表的字段尽可能用
NOT NULL
字段长度固定的表查询会更快
把数据库的大表按时间或一些标志分成小表
相关文章:数据库事务相关面试题