本篇是结合文章(一)继续展开,具体的一内容可以到博客里面浏览。
1.违反最左前缀法则 如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始,并且不跳过索引中的列。
2.范围查询右边的列,不能使用索引。
3.不要在索引列上进行运算操作, 索引将失效.
4.字符串不加单引号,造成索引失效。
5.以%开头的Like模糊查询,索引失效。如果仅仅是尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引失效。
1.设置合适的数值(tinyint int bigint),要根据实际情况选择
2.设置合适的字符串类型(char和varchar)char定长效率高,varchar可变长度,效率稍低
1.SELECT语句务必指明字段名称(避免直接使用select * )
2.SQL语句要避免造成索引失效的写法
3.尽量用union all代替union , union会多一次过滤,效率低
4.避免在where子句中对字段进行表达式操作
5.Join优化 能用inner join 就不用left join right join,如必须使用 一定要以小表为驱动, 内连接会对两个表进行优化,优先把小表放到外边,把大表放到里边。left join 或 right join,不会重新调整顺序
如果数据库的使用场景读的操作比较多的时候,为了避免写的操作所造成的性能影响 可以采用读写分离的架构。 读写分离解决的是,数据库的写入,影响了查询的效率
ACID
原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
脏读:一个事务读到另外一个事务还没有提交的数据。
幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了”幻影”。
不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。
隔离级别:
第一个是,未提交读(read uncommitted)它解决不了刚才提出的所有问题,一般项目中也不用这个。第二个是读已提交(read committed)它能解决脏读的问题的,但是解决不了不可重复读和幻读。第三个是可重复读(repeatable read)它能解决脏读和不可重复读,但是解决不了幻读,这个也是mysql默认的隔离级别。第四个是串行化(serializable)它可以解决刚才提出来的所有问题,但是由于让是事务串行执行的,性能比较低。所以,一般使用的都是mysql默认的隔离级别:可重复读
重做日志,记录的是事务提交时数据页的物理修改,是用来实现事务的持久性。 该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log file),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都存到该日志文件中, 用于在刷新脏页到磁盘,发生错误时, 进行数据恢复使用。
undo log可以实现事务的一致性和原子性。
回滚日志,用于记录数据被修改前的信息 , 作用包含两个 : 提供回滚 和 MVCC(多版本并发控制) 。undo log和redo log记录物理日志不一样,它是逻辑日志。 可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然, 当update一条记录时,它记录一条对应相反的update记录。当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。
redo log: 记录的是数据页的物理变化,服务宕机可用来同步数据
undo log :记录的是逻辑日志,当事务回滚时,通过逆操作恢复原来的数据
redo log保证了事务的持久性,undo log保证了事务的原子性和一致性。
这里两个log保证了一致性,原子性和持久性,那么事务中的隔离性是由排他锁来实现的,也就是锁单位可以是行数据。
全称 Multi-Version Concurrency Control,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突 MVCC的具体实现,主要依赖于数据库记录中的隐式字段、undo log日志、readView。
undolog:
回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志。 当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。 而update、delete的时候,产生的undo log日志不仅在回滚时需要,mvcc版本访问也需要,不会立即被删除