zoukankan      html  css  js  c++  java
  • 索引的底层理解

    引言

      

      最近看了很多文章,这里再补充一下对索引底层的理解,仅个人意见,有不对的,大家可以留言下,非常欢迎~

      关于什么是索引,索引的建立,索引不同存储引擎可以在之前的文章了解到
      请点击这里:http://www.cnblogs.com/houdashuai/p/6681680.html
      这次总结一下,重点说一下底层结构

    一、索引的分类;

      

      普通索引「INDEX」:   增加索引结构,对数据列增加普通索引

      全文索引「FULLTEXT」: 增加索引结构,全文索引适用于文章查询,一般用普通索引就可以

      唯一索引「UNIQUE」:  增加索引结构,数据不允许出现重复,但是可以为空,空就是空,不等于0,也不等于空字符串

      主键索引「PRIMARY」:  增加索引结构,数据不允许出现重复,但是不可以为空

      联合索引:       根据左前缀原则合理创建,这里不多介绍

    二、创建表时会影响到索引的因素:

      

      针对于数据库查询,数据库字段肯定是越小,越少的元素会很快,那么在创建表,对字段的约束尽量以数据类型为主:

        1. 尽量以INT数值去做索引列,因为数值的查询效率总是大于文字;

        2. 数据列字段尽量范围越小越好,这种区别在千万级数据库中或者单张表字段很多时会有很大差距,tinyint就是用tinyint,不要用int,或者char;

        3. 还有字段尽量给 NOT NULL,尽量给 NOT NULL,尽量给 NOT NULL,这个要注意下,因为索引对空值的判断很复杂,可以给默认值填充空字符串;

    三、使用SQL时会影响到索引的因素:


      会影响到全表扫描的语句,像 NOT IN 、LIKE、<>、!=、or......这些explain 看一下语句级别和影响行数注意一下
      说一下两个常用的点:
      1. limit:
        limit 一般用到分页,但是如果数据很多的话,一般都是这样写的 limit 100,200
        如果场景允许的话可以适用一下这种方式:
        WHERE uid>100 LIMIT 200

        原因:limit会产生全表扫描,但是可以用WHERE筛选掉一部分数据,这样会节省很多查询时间,大家可以尝试一下这种方式~

      2. *:count(0)、count(*)
        网上对星号的歧义有很多,这两种哪个效率高,我觉得用*号应用性更好一些(部分场景),每个项目都会封装model层,这些一般都是封装单张表的SQL

        SELECT COUNT(*) FROM `demo`;
        SELECT * FROM `demo`;

        如果查询涉及到一张表建议还是用*号,考虑到扩展性、及效率
        扩展性:网站业务扩展,字段增加,如果不用*号那就不可避免的要更改最底层的代码,这种操作很危险;
        效率:效率来讲,*号会自动匹配到这张表中查询效率最优的数据列,从而获取到数据,如果是单张表我还是建议用*号,但是如果是关联表就不建议使用*号了,关联表那影响查询效率就翻倍了。

    四、根据索引的优缺点去概述一下索引的底层结构

      

      优点:增加查询速度

      缺点:影响写的效率

      问题:为什么会影响写的效率。

      每创建一个索引,都会创建一条依据这个索引的索引查询结构,也就是平衡树结构。

      可以这样理解,每创建一条索引都会生成一个索引结构文件,这个文件存的不是数据,而是数据的【指针】,索引根据二分算法也就是B+Tree、B-Tree的算法去查询到数据的指针,再拿到数据。
      讲到这里就有一个问题,索引的产生肯定是维持在一个正确的平衡树状态,那么每一次做增、删、改的操作时就会重新排序索引文件结构,那么索引如果有一条,两条,三条,的时候,那么索引越多岂不是很影响写的效率,因为每一条索引结构都会重新排序,并且当数据量过于巨大时,每一次写操作,对于数据库的压力也会非常大;

      所有的优化都是空间换时间,或者时间换空间;
      这里想强调一下:对于优化而言网上有提供很多种,但是这里还是说一下级别,能在表,SQL,计算机硬件上做优化尽量先考虑这些,之后可以再考虑主从,读写分离,负载均衡,不到很卡顿尽量还是不要做分库分表,因为目前而言大都是关系型数据库居多,以关系为主,过多的做子表拆分也就扩大了关系型数据库的弊端,也可以考虑一下NoSQL,当然如果涉及到表设计需要分表这个另说,像这种关系型数据库,亿级以下的数据用索引,SQL优化,架构优化,读写分离,主从完全可以搞得定,如果还是卡,那就硬件提升一下,4G上8G,速度绝对有提升很多,尽量从其他方面考虑,MySQL毕竟也是一种开发语言,吼住上亿数据还是毛毛雨的~

  • 相关阅读:
    完整的UED流程
    curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection refused
    部署方案模板
    商城项目合作
    架构师分类
    k8s视图
    虚拟化通信技术
    AxureRP8 实现时间功能
    在AxureRP8中实现广告文字滚动效果
    获取当前网络中的电脑数目及MAC-通过MAC查找IP-通过IP查询机器名
  • 原文地址:https://www.cnblogs.com/houdabao/p/8665526.html
Copyright © 2011-2022 走看看