Btree+的存储结构
Explain
shown warnning 查看具体优化sql
explain:
id 越大优先级越高,相同,从上到下执行
select_type: simple,primary(复杂查询最外层的查询)
table
type:system > const > req_ref > ref > range > index > all
possible_keys 可能用到的索引
key: 计划使用索引
key_len: 使用索引的长度, varchar 3n+2 Null 1 char 3n
row: 扫描行数
extra: 文件排序 filesort order by groub by
索引优化:
全职匹配, 提高索引效率
最左匹配规则:
不要在索引上面做函数计算
like 左匹配
少用or或者in 之类的,可能不会用到索引
范围查询,小范围驱动大范围
sql优化:
前期:开发前,
建表的时候,主键使用自增整形,字段尽量使用整形表述,字符串的字段建立索引消耗是比较大的,枚举类型是存储空间比较小的;
根据业务建立索引,复合索引尽可能的覆盖大部分查询;
索引设定全词匹配
最左匹配规则:
不要在索引上面做函数计算
转化为日期范围查询,有可能会走索引
尽量使用覆盖索引,少用select * , 提高查询效率,有可能不会回表;
mysql 不等于,not exist, not in 无法使用索引而导致全表扫描, 小于等于, 大于等于,mysql会评估扫描范围,最终决定是否使用索引;
is null,is not null 一般情况下也无法使用索引
like 后模糊;
少用or和in, 不一定会使用索引;
索引下推
order by 和 group by use filesort/ user index
分页查询优化,
嵌套查询优化,小表驱动大表;
中期:
后期:
explain 慢日志, 建立索引
Mysql的结构:
Server层: 连接器, 分析器, 优化器 执行器, Binlog
Store层:InnoDb Myisam memory
索引下推:
索引下推: select * from test where name like "zhan%" and age = 3 and sex = 1;
在5.6以前走完第一个索引拿到值后就会进行回表,因为age和sex是无序,无法走索引,
在5.6开始, 在索引便利过程中,会对索引中的所有字段进行判断,过滤掉不符合条件的记录,减少回表次数,提升查询效率;
sql优化:
1. MySQL支持两种方式的排序filesort和index,Using index是指MySQL扫描索引本身完成排序。index
效率高,filesort效率低。
2、order by满足两种情况会使用Using index。
1) order by语句使用索引最左前列。
2) 使用where子句与order by子句条件列组合满足索引最左前列。
3、尽量在索引列上完成排序,遵循索引建立(索引创建的顺序)时的最左前缀法则。
4、如果order by的条件不在索引列上,就会产生Using filesort。
5、能用覆盖索引尽量用覆盖索引
6、group by与order by很类似,其实质是先排序后分组,遵照索引创建顺序的最左前缀法则。对于group
by的优化如果不需要排序的可以加上order by null禁止排序。注意,where高于having,能写在where中
的限定条件就不要去having限定了
事务属性; 原子性, 一致性, 隔离性, 持久化
事务: 读未提交 读已提交 可重复读 串行化
MVCC undo日志和 一致性试图readview 控制版本链实现隔离性,
在可重复读隔离级别下, 一致性试图在地磁sql查询就生成了,读已提交实在每次查询重新生成一致性视图read view
redo日志 bufferPool
MyISAM在执行查询语句SELECT前,会自动给涉及的所有表加读锁,在执行update、insert、delete操作会自
动给涉及的表加写锁。
InnoDB在执行查询语句SELECT时(非串行隔离级别),不会加锁。但是update、insert、delete操作会加行
锁
MyIsam 没有事务,没有行锁, 加了写锁;读锁会阻塞写,但是不会阻塞读。而写锁则会把读和写都阻
InnoDb 默认表锁, update,insert, delete 默认加行锁
Innodb存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面所带来的性能损耗可能比表级锁定会要更
高一下,但是在整体并发处理能力方面要远远优于MYISAM的表级锁定的。当系统并发量高的时候,Innodb
的整体性能和MYISAM相比就会有比较明显的优势了。
主从同步:
主库打开binlog日志,
从库会有一个IO线程和主库保持TCP连接,请求主库将binlog同步过来
主库dump一个IO线程, 通过这个TCP连接将binlog发给从库,从库写入到rely日志,
从库上的另一个sql线程会将binlog重操做,达到数据同步;
半同步复制, 是一个更新操作会等到写道从库的rely 日志,才返回给到客户端响应;如果没有响应, 会自动放弃,降级为异步