MySQL query optimization formula

全值匹配我最爱,最左前缀要遵守;

带头大哥不能死,中间兄弟不能断;

索引列上少计算,范围之后全失效;

LIKE百分写最后,覆盖索引不写星;

不等空值还有OR,索引失效要少用。
使用IN查询的时候,其实是范围查询,如果查询列是索引列则explain的结果是range类型
Group By操作会先排序然后再分组,如果分组的列不是索引列会使用Temporary Table和File Sort
IN和Exists优化原则:小表驱动大表.

eg: 

1、如果B表小于A表则IN优于Exists (B表驱动A表查询,可以看执行计划)
select id from A in (select id from B)

2、如果A表小于B表则Exists优于IN (A表驱动B表查询)
select id from A EXISTS (select id from B)
MySQL的可重复读的隔离级别使用了MVCC机制,SELECT不会更新版本号,是快照读(历史版本),INSERT, UPDATE, DELETE会更新版本号,是当前读(当前版本)。

1、其中幻读的情况就是,一个事务读取(只用SELECT是不会出现的,如果是用UPDATE WHERE操作就可能会出现这种情况)到了另外一个事务新增的数据。
出现这种原因主要是MVCC下分为:快照读和当前读。快照读就是读取数据的时候会根据一定规则读取事务可见版本的数据。 而当前读就是读取最新版本的数据。
1> 什么情况下使用的是快照读:(快照读,不会加锁)一般的 
select * from .... where ...
2> 什么情况下使用的是当前读:(当前读,会在搜索的时候加锁)
select * from .... where ... for update 
select * from .... where ... lock in share mode 
update .... set .. where ... 
delete from. . where ..
产生幻读的情况主要是快照读和当前读混用导致的,如果只使用快照读或者当前读则可以解决这个问题。

2、脏读:一个事务读取到了另外一个事务未提交的数据。

3、不可重复读:一个事务读取到了另外一个事务提交的数据(在一个事务中重复读的话会出现两次读到的数据不一致的情况)。

4、幻读可以使用Srializeable隔离级别,同时在某些场景下也能使用间隙锁(比如使用UPDATE USER SET NAME = 'laowu' WHERE ID > 5 AND ID < 100则其他SESSION没法插入这个范围的数据)来解决。

5、尽可能让所有的查询都走索引,不然可能会由行级锁升级为表锁。

6、锁的分类:

从性能上来说分为乐观锁(通过版本控制)和悲观锁
从对数据库的操作上分为:读锁(共享锁)和写锁(排他锁)
从对数据库操作的锁的粒度分为:行锁和表锁

 

Guess you like

Origin blog.csdn.net/qq_32323239/article/details/106393443