程序员在经过一段时间的数据库学习后,总会对mysql如何降低失效这一问题抓耳挠腮,现在就让六星教育告诉你这一问题的答案吧!在哪里能真正的学好编程呢,拭目以待。
最左匹配原则
1、先定位该sql的查询条件,有哪些,那些是等值的,那些是范围的条件。
2、等值的条件去命中索引最左边的一个字段,然后依次从左往右命中,范围的放在最后。
索引分析讲解
1、mysql的索引分为聚簇索引和非聚簇索引。
聚簇索引:宏观上数据和索引存储在一个文件中。底层上B+Tree 的叶子节点存储行数据代表是Innodb,
非聚簇索引:宏观上数据和索引分别人存储到不同文件,底层上B+Tree 的叶子节点存储为物理指针。 代表是myisam,
聚集规则是:以主键字段创建索引为聚集索引。没有主键则选第一个不允许为NULL的唯一索引;还没有就使用innodb的内置rowid为聚集索引。
非主键字段创建的索引称为二级索引,或者辅助索引。二级索引下b+Tree的叶子节点存放的是主键值。
所以通过二级索引查找的是主键,拿到主键后还需要去聚集索引上面去查找数据。这个过程我们称之为回表
2、索引的高度
聚集索引的高度决定了根据主键取数据的理论IO次数。二级索引读取数据的理论IO次数=聚集索引的IO次数+二级索引查找IO次数。实际上可能要不了这么多IO。因为索引的分支节点所在的Page一次读取会加载到mysql内存中。
mysql的一页数据大小默认是16K,可以根据索引列的长度粗略估算索引的高度。
sql优化依据
在where条件上,使用的条件或规则,最终都会被提取到Index Key (First Key & Last Key),Index Filter与Table Filter之中。
Index First Key,是用于定位索引的初始范围,因此只能在索引第一次Search Path(沿着索引B+树的父节点一直遍历,到索引正确的叶节点位置)时使用,只会判断一次;
Index Last Key,用于定位索引的结束范围,因此对于初始范围之后读到的每一条索引记录,均需要判断是否已经超过Index Last Key的范围值,若超过,则结束当前查询;
Index Filter,只能用于过滤索引查询范围中不满足匹配条件的记录,因此对于索引范围中的每个数据值,都要与Index Filter进行对比,若不满足Index Filter就直接丢弃,然后在读取索引下一行记录;
Table Filter,是最后一道where条件的过滤,用于过滤通过前面索引的记录,此时的记录已经满足了Index First Key与Index Last Key的范围,并且满足Index Filter的条件,回表读取完整的记录,判断完整记录是否满足Table Filter中的查询条件,同样的,若不满足,直接跳过当前记录,继续读取满足索引查询后保留数据中的下一条记录,若满足,则返回记录,此记录就满足了where的所有条件,最后就可以返回给前端了
SQL执行流程分析
一条sql语句要执行完成需要经历什么样的过程
当一条sql语句提交给mysql数据库进行查询的时候需要经历以下几步
1、先在where解析这一步把当前的查询语句中的查询条件分解成每一个独立的条件单元
2、mysql会自动将sql拆分重组
3、然后where条件会在B-tree index这部分进行索引匹配,如果命中索引,就会定位到指定的table records位置。如果没有命中,则只能采用全部扫描的方式
4、根据当前查询字段返回对应的数据值
Mysql - 什么情况下索引不会被命中
1、如果where条件中有 or ,即使其中有条件字段为索引列也不会使用
注意:要想or索引生效,可以将or条件中的每个列都加上索引
如果OR其中条件组合里面,有一个条件没有索引时,建议使用 union ,拼接多个查询语句。
2.、like查询如果以%开头,索引不会命中
当然有一种情况下,例如: ‘test%’ 它只查询索引列,就会用到索引,但是这种情况下跟是否使用%无关,因为查询索引列本身就会用索引
3. 如果列类型是字符串,在条件里面一定要将数据使用字符串的引号标注起来,否则不会使用索引
4. 无查询条件或条件不建立索引
5. where条件后面,在索引列上使用函数(+, - ,*,/), 当然你可以建立函数索引来解决
6. 使用 not in, not exist
7. B-tree 索引 is null 不会走, is not null 会走。因为B树索引可以存储NULL值,但不允许索引字段全部为NULL,若索引字段全部为NULL,索引不会存储。
扫码二维码 获取免费视频学习资料
- 本文固定链接: http://phpxs.com/post/7651/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料