美文网首页
MySQL基础

MySQL基础

作者: ES_KYW | 来源:发表于2021-05-25 15:18 被阅读0次
    1.mysql的索引原理和数据结构
    目录查询,B+树结构
    2.B+树和B树的区别是什么
    二分查找树->平衡二叉树->B树->B+树
    B树一个节点上可以存储多个键值和数据
    B+树,非子叶节点上不存储数据,存储多个键值;子叶节点上顺序存储键值和数据(聚集索引),子叶节点不存储数据,存储该列对应的主键,查到主键后回表查询,再走聚集索引的查询流程。
    
    3.mysql聚簇索引和非聚簇索引的区别
    主键作为索引和非主键列作为索引
    聚集索引:叶子节点顺序存储数据
    非聚集索引:叶子节点不存储数据,存储该列对应的主键,然后根据主键回表查询。
    如果不设置主键,MySQL默认会创建主键;
    
    4.使用mysql索引都有什么原则
    联合索引会有最左原则;
    覆盖索引,查询列刚好是索引,默认会使用该索引
    
    5.不同的存储引擎是如何进行实际存储的
    Myisam:存储数据信息
    Innodb:存储地址和文件
    6.mysql组合索引的结构是什么样的
    
    7.mysql索引如何进行优化
    1.expain分析索引的使用情况;
    2.索引字段不要太长;
    3.多列索引查询时可使用联合索引;
    4.尽量避免使用子查询;
    5.用IN来替换OR
    select * from person where name = 'jack' or name = 'lucy';
    select * from person where name in ('jack' , 'lucy');
    6.读取适当的记录LIMIT M,而不要读多余的记录
    select * from person where age > 10 limit 10;
    7.不要使用NOT等负向查询条件;
    二分查找的特点,左边查询不匹配会到右边查询,若使用不等于,则需要全表查询;
    8.尽量不用select *
    SELECT *增加很多不必要的消耗(cpu、io、内存、网络带宽);
    9.区分in和exists
    select * from 表A 
    where id in (select id from 表B)
    select * from 表A 
    where exists(select * from 表B where 表B.id=表A.id)
    如果是exists,那么以__外层表为驱动表,先被访问__;
    如果是IN,那么__先执行子查询__;
    所以IN适合于外表大而内表小的情况;
    EXISTS适合于外表小而内表大的情况。
    10.优化Group By语句
    如果对group by语句的结果没有排序要求,要在语句后面加 order by null(group 默认会去排序);
    
    11.索引优化:
    性能优化,left join 是由左边决定的,左边一定都有,所以右边是我们的关键点,建立索引要建在右边。当然如果索引是在左边的,我们可以考虑使用右连接;
    Tips:Join左连接在右边建立索引;组合索引则尽量将数据量大的放在左边,在左边建立索引
    
    12.避免索引失效
    1、如果索引了多列,要遵守最左前缀法则,指的是查询从索引的最左前列开始并且不跳过索引中的列。Mysql查询优化器会对查询的字段进行改进,判断查询的字段以哪种形式组合能使得查询更快,所有比如创建的是(a,b)索引,查询的是(b,a),查询优化器会修改成(a,b)后使用索引查询
    2、不在索引列上做任何操作,(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描。)
    3、存储引擎不能使用索引中范围条件右边的列。
    如这样的sql: select * from user where username='123' and age>20 and phone='1390012345',其中username, age, phone都有索引,只有username和age会生效,phone的索引没有用到。
    4、尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致));
    如select age from user减少select *;
    5、mysql在使用不等于(!= 或者 <>)的时候无法使用索引会导致全表扫描;
    6、is null, is not null 也无法使用索引,在实际中尽量不要使用null;
    7、like 以通配符开头(‘%abc..’)mysql索引失效会变成全表扫描的操作;
    所以最好用右边like 'abc%'
    8、字符串不加单引号索引失效;
    9、少用or,用它来连接时会索引失效;
    10、尽量避免子查询,而用join;
    
    

    一、为什么用自增列作为主键

    1、如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引。
    如果没有显式定义主键,则InnoDB会选择__第一个不包含有NULL值的唯一索引作为主键索引__。
    如果也没有这样的唯一索引,则InnoDB会__选择内置6字节长的ROWID作为隐含的聚集索引__(ROWID随着__行记录的写入而主键递增__,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)。
    2、数据记录本身被存于主索引(一颗B+Tree)的叶子节点上,这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放;
    因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)
    3、如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页
    4、如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置;
    此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销
    同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面
    

    二、为什么使用数据索引能提高效率

    MySql默认是B+树结构,原因是默认有主键索引。
    使用索引查询的时候走索引的查询流程,同时索引会将子叶节点页中的数据按序排序;
    不使用索引查询的时候就会遍历整张表;
    https://www.cnblogs.com/xiaoshahai/p/12028737.html

    索引可以将无序内容转换为有序的一个集合(相对),就如同新华字典,如果没有目录,那么查询一个汉字就需要很长时间了;
    如果没有索引我们查询数据是需要遍历双向链表来定位对应的page,现在通过索引创建的“目录”就可以很快定位对应页上了;
    数据索引的存储是有序的;
    在有序的情况下,通过索引查询一个数据是无需遍历索引记录的
    极端情况下,数据索引的查询效率为二分法查询效率,趋近于 log2(N)
    

    什么是哈希索引

    哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索
    时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希
    算法即可,是无序的,如下图所示:
    
    image.png
    哈希索引的优势:
    等值查询,哈希索引具有绝对优势(前提是:没有大量重复键值,如
    果大量重复键值时,哈希索引的效率很低,因为存在所谓的哈希碰撞问题。)
    哈希索引不适用的场景:
    不支持范围查询
    不支持索引完成排序
    不支持联合索引的最左前缀匹配规则
    

    为什么说B+比B树更适合实际应用中操作系统的文件索引和数据库索引?

    1、B+的磁盘读写代价更低。
    
    B+的内部结点并没有指向关键字具体信息的指针,因此其内部结点相
    对B树更小。
    如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能
    容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也
    就越多。相对来说IO读写次数也就降低了。
    
    2、B+-tree的查询效率更加稳定。
    由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关
    键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点
    的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。
    

    MySQL联合索引

    1、联合索引是两个或更多个列上的索引。
    对于联合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。
    例如索引是key index (a,b,c). 可以支持a 、 a,b 、 a,b,c 3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效。
    2、利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引不同于使用两个单独的索引。
    复合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。
    

    如果您知道姓,电话簿将非常有用;如果您知道姓和名,电话簿则更为有用,但如果您只知道名不知道姓,电话簿将没有用处

    image.png

    联合索引和多个单列索引的区别

    因为MySql优化器原因,多个单列索引查询时查询并不会按照索引的前后顺序去查询,可能会导致查询效率变低。
    联合索引遵循最左原则,可以让SQL优先查询最最便的索引,之后查询后面的,不会被SQL优化,会按照顺序搜索;

    相关文章

      网友评论

          本文标题:MySQL基础

          本文链接:https://www.haomeiwen.com/subject/qfifdltx.html