mysql 索引原理

索引

数据库索引,是数据库管理系统中一个排序的数据结构(存储在磁盘中),以协助快速查询,更新数库表中的数据。

索引存储结构 

平衡二叉树 (基于磁盘)

  • 左右树深度差绝对值不能超过 1 
  • 左子树节点 < 父节点
  • 右子树节点 > 父节点

多路平衡查找树 BTREE

  • 频繁修改的数据字段 不建议添加索引   索引存储节点更新耗时长

加强版多路平衡查找树   B+TREE

  • 扫库,扫表能力更强
  • 磁盘读写能力更强 (降低io,节省磁盘空间) 
  • 排序能力更强  (叶子节点本身为有序结构)
  • 效率更加稳定

索引类型

PRIMARY  主键索引(不允许重读,并且值不能为空)

UNIQUE  唯一索引(不允许重复,但可以为空)

FULLTEXT 全文索引    需要like   "%aaaa%"  时使用   语法应为  MATCH (col1,col2,...) AGAINST (expr [search_modifier])

search_modifier:
  {
       IN NATURAL LANGUAGE MODE
     | IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
     | IN BOOLEAN MODE
     | WITH QUERY EXPANSION
  }

natural language search

  • 全文搜索默认是大小写不敏感的
  • 当不指定模式修饰符时,使用的是自然语言修饰符
  • MATCH中的列必须和全文索引中的列匹配
  • 当在WHERE子句中使用MATCH时,会返回相关性大于0的记录,并按照相关性的得分降序排列
SELECT COUNT(*) FROM articles
    WHERE MATCH (title,body)
    AGAINST ('database' IN NATURAL LANGUAGE MODE);

boolean search可以通过一些符号来增加或减少某些词在搜索中所占的权重

-- 匹配既有管理又有数据库的记录
SELECT * FROM articles WHERE MATCH (title,body) 
    AGAINST ('+数据库 +管理' IN BOOLEAN MODE);

-- 匹配有数据库,但是没有管理的记录
SELECT * FROM articles WHERE MATCH (title,body)
   AGAINST ('+数据库 -管理' IN BOOLEAN MODE);

存储引擎 == 表类型

常用 InnoDB(5.5之后默认),MyISAM

  • 查询数据文件存储位置

聚集索引:决定了数据物理存放顺序的索引,(B+TREE 叶子节点上的存放顺序)

一张表不可能没有索引存在3个自动创建的隐藏字段

  • 存在主键索引 则主键索引为聚集索引
  • 不存在则查找第一个没有空值的唯一索引
  • 都不存在则使用隐藏字段rowid作为聚集索引

辅助索引

除了主键索引其它都为辅助索引

InnoDB 引擎  辅助索引查询(先扫描自己的B+TREE,再扫描主键索引B+TREE)

 

索引使用

使用explain关键字分析sql

  • 不用在重复值比较多的列建立索引  

联合索引

  • 最常用的查询字段放在前边
  • where 条件顺序不影响索引的使用 
  • 联合索引的第一个字段  可以单独查询 联合索引依旧可以使用,其他字段查询不使用索引
创建索引
ALTER TABLE `u_user` ADD INDEX comidx_name_phone (NAME,phone)

使用索引
EXPLAIN SELECT * FROM `u_user` WHERE NAME = "21" AND phone = "18719445972"
使用索引
EXPLAIN SELECT * FROM `u_user` WHERE phone = "18719445972" AND NAME = "21"
使用索引
EXPLAIN SELECT * FROM `u_user` WHERE NAME = "21"
不使用索引
EXPLAIN SELECT * FROM `u_user` WHERE phone = "18719445972"

覆盖索引

查询的字段为索引字段则不会再次扫描扫描主键索引的B+TREE

出现 Using index则为覆盖索引
不是覆盖索引
EXPLAIN SELECT * FROM `u_user` WHERE NAME = "21" AND phone = "18719445972"
是覆盖索引
EXPLAIN SELECT name,phone FROM `u_user` WHERE phone = "18719445972" AND NAME = "21"
是覆盖索引
EXPLAIN SELECT phone FROM `u_user` WHERE NAME = "21"
是覆盖索引 不使用索引查询 但是查询字段为索引字段,则也不扫描主键索引树
EXPLAIN SELECT phone FROM `u_user` WHERE phone = "18719445972"
  • 因为覆盖索引提高数据查询效率 则不要使用select * from .....   查询数据

存在索引但不适用的情况

  • 在索引列使用函数或者表达式、计算
  • 字符串不加引号,出现隐式转换
  • like 条件前面带%  即 "%aaa"   但是  "aaa%" 可以使用索引
  • 负向查询: NOT LIKE、!=  (<>)、NOT  IN
  • 使不使用索引由optimizer(优化器)决定
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值