数据库事务
数据库事务代表一次完整的操作
隔离级别
原因:多个单元操作,并发执行会出现,脏读,不可重复读 幻读
解决方案<br>进行并发处理时候隔离
已提交读 (R-C)
读取时候加行级共享锁,一旦读完立刻释放,读取成功后释放
可重复读 (R - R)
事务默认级别, 读取时候加行锁,事务结束释放
串行化 (SE)
无并发可言 ,读取时候加表锁
实现(InnoDB)
锁
mvcc
生成redoLog,进行数据回滚
CAS 版本控制 + 读写分离
执行计划
explain select * from users
ID 越大 越先执行
id号分为三种情况:<br>1、如果id相同,那么执行顺序从上到下<br>2、如果id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行<br>3、id相同和不同的,同时存在:相同的可以认为是一组,从上往下顺序执行,在所有组中,id值越大,优先级越高,越先执行
select_type 查询类型
主要用来分辨查询的类型,是普通查询还是联合查询还是子查询<br>sample:简单的查询,不包含子查询和union<br>primary:查询中若包含任何复杂的子查询,最外层查询则被标记为Primary<br>union:若第二个select出现在union之后,则被标记为union<br>dependent union:跟union类似,此处的depentent表示union或union all联合而成的结果会受外部表影响<br>union result:从union表获取结果的select<br>subquery:在select或者where列表中包含子查询<br>dependent subquery:subquery的子查询要受到外部表查询的影响<br>DERIVED: from子句中出现的子查询,也叫做派生类,<br>UNCACHEABLE SUBQUERY:表示使用子查询的结果不能被缓存<br>uncacheable union:表示union的查询结果不能被缓存:sql语句未验证
type 访问方式
type显示的是访问类型,访问类型表示我是以何种方式去访问我们的数据,最容易想的是全表扫描,直接暴力的遍历一张表去寻找需要的数据,效率非常低下,访问的类型有很多,效率从最好到最坏依次是:<br><br>system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
possible_key 显示可能用到那些索引
key 实际用到索引
rows 预估行数
extra 额外信息 例如排序类型 、覆盖索引
索引优化
索引基础知识
索引结构
哈希表
B+树
了解常用数据结构 哈希表、二叉树、红黑树、B树、B+树
优点
减少服务器数据检索时间 , 索引列已经排好顺序
随机IO变为顺序IO
用途
快速匹配where子句
MySQL会排除多余数据扫描,总会命中行数最少的索引
索引匹配方式
全值匹配
匹配最左前缀
匹配列前缀
匹配范围
精确匹配某一列并范围匹配另一列
只访问索引查询
hash索引
memory 存储引擎
基于哈希表实现,只有精确匹配才能被查找
只存储hash值,数据紧凑,索引非常快
限制
只包含hash值,不进行字段存储,不是顺序存储,无法进行排序
不支持部分列存储
考虑哈希冲突情况,冲突比较多会造成数据列维护不方便,代价也很高
使用案例
当需要存储大量的URL,并且根据URL进行搜索查找,如果使用B+树,存储的内容就会很大<br>select id from url where url=""<br>也可以利用将url使用CRC32做哈希,可以使用以下查询方式:<br>select id fom url where url="" and url_crc=CRC32("")<br>此查询性能较高原因是使用体积很小的索引来完成查找
组合索引
包含多个列作为索引,需要注意的是正确的顺序依赖改索引的查询,同事满足最左匹配原则
案例,建立索引 a,b,c
a=3 and b=4 and c=5
a,b,c
a = 3 and b>10 and c = 7
a,b
a = 3 and b like '%1%' and c = 7
a
聚簇索引与非聚簇索引
聚簇索引
优点
可以把相关数据保存在一起
数据访问更快,不需要另外查找
覆盖索引扫描可以直接到叶节点
缺点
聚簇数据极大的现在了数据IO的扩展性
插入速度验证依赖插入书序,按照主键插入顺序最快
更新聚簇索引列代价很高,会强制将每个更新的行移动到新的位置
新插入行如果超过索引页大小,会导致页分裂的问题
全表扫描变慢
非聚簇索引
覆盖索引
介绍
如果一个索引包含所有需要查询的字段的值,称之为覆盖索引
不是所有类型的索引都成为覆盖索引,覆盖索引必须要存储索引列的值
不同存储引擎实现索引的方式不同,不是所有引擎都支持覆盖索引,memory不支持
优势
索引条目通常小于数据行大小,如果只需要读取索引,会极大的减少数据访问
索引按照顺序存储的,对IO密集型范围查找会比随机查找快很多
IO密集型
InnoDB是聚簇索引,覆盖索引效率特别高
案例
优化细节
索引列进行扫描时,尽量不要用表达式,将计算放到业务层而不是数据层
尽量使用主键索引,避免发生回表
使用前缀索引
使用索引扫描进行排序
union all , in , or 都能够使用索引,推荐使用in
范围列可以用到索引 但是只能用一列索引
强制转换可能会导致全表扫描
更新十分频繁的操作不宜建立索引
索引列不能为空
表进行连接时候,最好不要超过三张表,因为join需要的字段数据类型必须一致
能使用limit时候尽量使用limit limit 限制输出
单表索引建议控制在5个以内
组合索引字段不应该超过5个
索引监控
索引优化简单案例
面试
高度计算
InnoDB存储引擎默认一个数据页大小为16kb,非叶子节点存放(key,pointer),pointer为6个字节,key为4个字节,即非叶子节点能存放16kb/14左右的key,pointer,而叶子节点如果一条数据大小为100字节,那一个叶子节点大约可存放160条数据。<br>如果高度为3,则可存放数据为:16kb/14 * 16kb/14 * 160大约1亿多数据。<br>因此InnoDB存储引擎b+树的高度基本为2-3.
主从复制
主 -- 从 进行 log复制
1:主库 binlog 日志生成后进行网络传输<br>2:从库将binlog 日志落盘 SQL 解析<br>3:5.7 以后 IO线程是多线程,从库SQL解析是串行化解析的,延迟非常高 relaylog
主库 1000/s 操作以后会造成延迟1 、 2 ns 的延迟
问题解决
semi sync<br>半同步复制
必须同步到从库,才操作成功
SQL 线程开启并行复制
show status ;<br>seconds_behind_master 查看当前落后从库的状态 ms
分库 、 削峰<br>分多个库,开启并行复制<br>代码、重新设计
慢查询查看
开启慢查询日志
slow_query_log -- on 打开慢查询
show_query_log_file -- 默认记录文件
log_query_time -- 10S 超过执行时间会被记录
explain 分析sql
type 索引类型
联合索引最左匹配原则