MySQL索引初识

197 阅读3分钟

Mysql架构:


  • bin log:存在于mysql的server层,用与mysql的主从复制

1.索引数据结构:

  • 二叉树:

  • 红黑树:大数据范围树的高度不可控

  • Hash表:对索引进行一次hash运算就能得到数据的磁盘文件指针,不支持范围查找

  • B-Tree:节点大小16k

举例:max.dgree=4



  • B+Tree:

    • 1、节点大小16k,每个非叶节点1170元素

    • 2、树高不会超过4,一般是3,3层满两千多万行数据

    • 3、B+树每个索引和叶子数据都有指针,而且最下层叶子节点内和节点之间的数据是从大到 小依次排列的,这样就可以快速实现范围查找。


2.数据库存储引擎(作用于表级别):

MyISAM:(非聚集索引)

  • 只支持表锁、不支持外键、不支持事务、进行count(*)时查询快的前提是在语句中不加入条件描述,不然依旧是全局扫描才能得到。

  • frm文件:定义的表结构,表信息文件

  • MYD文件:存储数据行

  • MYI文件:存储索引,数据结构为b+树

  • 过程:首先在MYI文件中根据数据结构找到目标值,目标值是索引“key”和磁盘文件指针“value”,然后通过磁盘文件指针在磁盘中的MYD文件中找到数据返回。


InnoDB(聚簇索引):

  • 既支持表锁也支持行锁、支持外键、支持事务

  • 依附有Redo log和Undo log

  • frm文件:定义的表结构,表信息文件

  • ibd文件:存储数据行和索引,数据结构为b+树

  • 聚集索引:叶节点包含了完整的数据记录和索引==》

  • 为什么InnoDB表必须有整型自增主键(默认建立自增隐藏主键+根据主键建立索引):主键(建议使用自增主键,不能以uuid作为主键)索引用来根据B+树存储数据,整形数据进行比较大小时很快,节约存储空间,利于查找修改;自增主键能够避免树的分裂,由于B+树的结构,叶节点的数据是从左往后增加的,自增就可以直接在后面添加数据,效率高。


联合索引(联合几个字段一起建立一个联合索引):先比较相同字段,在第一个字段相同的情况下,进行第二个字段的比较。依次往下。


  • 举例:假设有一个product表:shop_id、product_id、gmt_creat

    • 建立联合索引:creat index (shop_id、roduct_id、gmt_creat)

    • 1、全列匹配:就是where条件里从左往右依次用到了这三个index

      • select * from product where shop_id=1 and product_id=1 and gmt_creat=‘2019-01-01 10:00:00’;

    • 2、最左前缀原则:使用最左边的一个或者几个(必须是依次连续的

      • select * from product where shop_id=1 and product_id=1;

      • shop_id、roduct_id是连续的,最左开始的

      • select * from product where shop_id=1 and gmt_creat=‘2019-01-01 10:00:00’

      • 这里就因为虽然是从最左边开始的,但是不是连续的,这样虽然在查shop_id=1的时候是按照索引查询,但是后续的gmt_creat=‘2019-01-01 10:00:00’是根据shop_id=1查询出来的有效数据进行遍历扫描而来的

      • select * from product where product_id=1;

      • 这里没有从最左字段开始进行查询,这就不是按照索引进行查询了,低级错误。

    • 3、前缀匹配

      • 如果查询条件是like,那么只有like 'xx%'其中%必须放后面

      • select * from product where shop_id=1 and product_id=1 and gmt_creat=‘2019%’;

    • 4、范围列匹配

      • 如果又>=,<=,between操作,只能是符合最左前缀的索引才能进行索引查询

      • select * from product where shop_id>=1 and product_id=1

        • 这里就只有shop_id能够按照索引进行查询了,而product_id是根据shop_id范围索引查询的结果遍历得来的

  • 注意

    • 一般一个表就建立2-3个索引就行了,因为索引本身就需要消耗磁盘空间,而且在高并发数据库操作下会导致性能的损耗