mysql事务 特性: 1、原子性<数据库事务不可分割的单位,要么都做,要么都不做> 2、一致性<事务的操作不会改变数据库的状态,比方说唯一约束> 3、隔离性<事务是相互不可见的> 4、持久性<事务一旦提交,即使宕机也是能恢复的> 分类 1、扁平事务<使用最频繁的事务,要么都成功提交,要么都失败回滚> 2、带有扁平点的扁平事务<允许事务回滚到同一个事务中比较早的一个状态> 3、链事务<回滚到最近的一个保存点,在所有的事务都提交之后才会释放锁,并且下一个事务的开始需要上一个事务来进行通知> 4、嵌套事务<树结构,只有当父级事务提交之后子级事务才会提交,任意一个父级事务的回滚都会导致下面的子级事务回滚> 5、分布式事务<操作两个不同的数据库,使其实现数据的同步,例如将中国银行的钱转到工商银行,这个不同银行的不同数据库,为分布式事务> 隔离级别 1、read uncommittted<脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据> 2、read committed<不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。> 3、repeatable read<幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。> 4、serializable<锁表,不会出现意外情况> |
锁 1、lock 1、共享锁<s lock>允许事务读取一行数据(共享锁允许多个事务来读取相同的数据,因为读取不会改变数据,但是不能与排他锁共存,当有事务想要update数据的时候就要等共享锁释放之后才能使用排他锁进行update) 2、排他锁<x lock>允许事务更新或者是删除一条数据(当排他锁进行了行数据的锁定的时候就必须等这个锁释放之后下一个锁才能进来,也就是说必须当数据更新完成之后才能接收下一个事务的锁) 3、意向共享锁<is lock>事务想要获得一张表某几行的共享锁 4、意向排他锁<ix lock>事务想要获得一张表的某几行的排他锁 2、latch<轻量级锁,锁的时间非常短,用来操作临界资源> 3、一致性的非锁定读 4、一致性锁定读 5、死锁 |
sql优化原则 1、选择需要优化的SQL 2、Explain和Profile入手 1、任何SQL的优化,都从Explain语句开始;Explain语句能够得到数据库执行该SQL选择的执行计划; 3、永远用小结果集驱动大的结果集 4、在索引中完成排序 5、使用最小Columns 6、使用最有效的过滤条件 7、避免复杂的JOIN和子查询 |
JOIN的原理 1、JOIN的原理: 2、JOIN的优化原则: 1,尽可能减少Join 语句中的Nested Loop 的循环总次数,用小结果集驱动大结果集; |
执行计划与执行明细 1,Explain:可以让我们查看MYSQL执行一条SQL所选择的执行计划; 1,ID:执行查询的序列号; 1,DEPENDENT SUBQUERY:子查询中内层的第一个SELECT,依赖于外部查询的结果集; 3,table:这次查询访问的数据表; 1,all:全表扫描 5,possible_keys:可选的索引;如果没有使用索引,为null; 6,key:最终选择的索引; 7,key_len:被选择的索引长度; 8,ref:过滤的方式,比如const(常量),column(join),func(某个函数); 9,rows:查询优化器通过收集到的统计信息估算出的查询条数; 10,Extra:查询中每一步实现的额外细节信息 1,Distinct:查找distinct 值,所以当mysql 找到了第一条匹配的结果后,将停止该值的查询而转为后面其他值的查询; 2,Profiling:可以用来准确定位一条SQL的性能瓶颈; 1,开启profiling:set profiling=1; status是执行SQL的详细过程; profiling只对本次会话有效; |
执行流程 1、查询缓存 |
表结构对性能的影响
1、冗余数据的处理(可以提高系统的整体查询性能<三范式>) 1、每一列只能有一个值 2、大表拆小表 1、一般不会设计属性过多的表 3、根据需求展示更加合理的表结构 4、常用属性分离为小表 |
索引 1、类型 1,Normal:普通的索引;允许一个索引值后面关联多个行值; 2、方法 1,b-tree:是一颗树(二叉树,平衡二叉树,平衡树(B-TREE)) hash索引的缺点: 1,hash索引只能适用于精确的值比较,=,in,或者<>;无法使用范围查询; 3、创建 1,较频繁的作为查询条件的字段应该创建索引; 2,唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件; 作为索引的列,如果不能有效的区分数据,那么这个列就不适合作为索引列;比如(性别,状态不多的状态列) 3,更新非常频繁的字段不适合创建索引;原因,索引有维护成本; 4,不会出现在WHERE 子句中的字段不该创建索引; 5, 索引不是越多越好;(只为必要的列创建索引) 1,不管你有多少个索引,一次查询至多采用一个索引;(索引和索引之间是独立的) |