mysql索引

数据量小的时候,所有数据都能在内存中,全表扫描也不慢
但是数据量变大,查询频率变高,内存不能缓存所有数据时,就需要索引了
索引在引擎层

B-tree

一般是这个
B+树结构存储



平衡查找树,每个叶子到root距离相同
,所有数据都按顺序存放在同层叶节点,叶之间指针连接,具体实现各引擎不同
叶子MyISAM通过物理位置引用行,Innodb通过主键

从根节点开始搜索
适合范围查找

什么样情况适合:
  • 全值匹配 =
  • 最左前缀查询 where的第一个
  • 列前缀 order_sn like '9876%'
  • 范围 > <
  • 精确匹配左前列,范围匹配另外一列
  • 只访问索引查询
  • order by group by
用不到的情况
  • 命中大多数数据 还不如全表扫描 不用索引了
  • 不是索引最左列 如 "订单号 订单日期"联合索引,订单号是最左列, 'where 订单日期' 这样就用不到索引
  • 不能跳过索引中的的列 [日期 下单人姓名 电话]联合索引 where [日期 电话] 不行
  • not in 和!=不行
  • 某列范围查询 右边的列就无法使用索引

Hash索引

特点

innodb的Hash索引 会自动根据访问的频率和模式,betree索引的使用情况来自动地为某些热点页建立哈希索引 又称自适应hash索引

  • 基于hash表 必须精确==匹配 模糊和范围不行
  • 对索引中的列,会合起来算一个hash码存储,只能全值匹配,只存索引让数据紧凑,查找非常快
限制
  • 二次查找:先找到对应的行 对行的数据进行读取(betree可能直接有存)
    但是经常被访问到的行,一般在内存中,访问速度很快,这点对性能的影响不明显
  • 顺序打乱 无法范围,排序,部分查找
  • 如果 hash冲突太多 影响查找和维护,所以不适合用在选择性差的列 比如性别,而是适合身份证号这种
  • 不能避免表扫描, 就是要回表

索引的作用

  • 大大减少存储引擎需要扫描的数据量
    innodb以页(默认16k)为单位读取,索引的大小比一行原本的大小小得多,需要读取的页数变少
  • 帮助排序,避免使用临时表
  • 数据行的物理地址通常是随机分布,索引是顺序,变随机io为顺序io,根据充分发挥io性能

索引性能损耗

  • 写入,需要索引信息维护
    innodb有插入缓存把多次插入变成一次,为了写入速度改删除所有索引,除了主键递增
  • 索引 增加 查询优化器 选择时间

索引优化策略

  • 索引列不能表达或函数


    改写
  • betree索引的键 innodb最大限制767字节(大概255个字) 注意字符串类型 用前缀索引 要注意选择性
    CREATE INDEX index_name ON table(col_name(n));
  • 联合索引的顺序
    经常使用的列(除非是状态这种选择性差的)→选择性高的→宽带小的列

覆盖索引

包含了查询全部值的索引


using index 直接在主键索引上完成查询和所有数据的获取

Extra: Using where 不能从索引得到所有数据,得把数据都找到放到内存再过滤

覆盖索引,因为那个actor_id虽然没有索引却是主键

Extra 情况
(1)using index condition ,先在二级索引上使用索引查找到主键ID,然后在主键索引上通过主键ID进行查找。这里之所以需要去主键索引上查,是因为select 需要的数据,二级索引不能完全提供
explain SELECT * from user_man where manname = 'zzk';
(2)using where ,直接在主键索引上过滤数据,必带where子句,而且用不上索引
explain select * from user_man where manage in (9,10);
(3)using index,直接在主键索引上完成查询和所有数据的获取,一般是只获取主键ID
explain select manid from user_man
(4)Using where; Using index,直接在二级索引上获取全部数据(覆盖索引)
explain select manname,manid from user_man where manname = 'yjz'
Mysql explain-Extra(using where,using index)使用详解

除此之外都是二级索引(就是我们自己建的):
mysql中每个表都有一个聚簇索引(clustered index ),除此之外的表上的每个非聚簇索引都是二级索引,又叫辅助索引(secondary indexes)。
以InnoDB来说,每个InnoDB表具有一个特殊的索引称为聚集索引。如果您的表上定义有主键,该主键索引是聚集索引。如果你不定义为您的表的主键 时,MySQL取第一个唯一索引(unique)而且只含非空列(NOT NULL)作为主键,InnoDB使用它作为聚集索引。如果没有这样的列,InnoDB就自己产生一个这样的ID值,它有六个字节,而且是隐藏的,使其作 为聚簇索引。mysql中每个表都有一个聚簇索引(clustered index ),除此之外的表上的每个非聚簇索引都是二级索引,又叫辅助索引(secondary indexes)。
以InnoDB来说,每个InnoDB表具有一个特殊的索引称为聚集索引。如果您的表上定义有主键,该主键索引是聚集索引。如果你不定义为您的表的主键 时,MySQL取第一个唯一索引(unique)而且只含非空列(NOT NULL)作为主键,InnoDB使用它作为聚集索引。如果没有这样的列,InnoDB就自己产生一个这样的ID值,它有六个字节,而且是隐藏的,使其作 为聚簇索引。

不该使用的情况:

  • 有的存储引擎不支持覆盖索引
  • 太多列

排序

  • 通过排序操作
  • 很快 btree按照索引顺序扫描数据 explain没有 Extra: Using filesort就是
    条件苛刻Order By的字段
    1.与索引顺序完全一致,
    2.所有升序降序一致
    3.全部在关联表第一张表
innodb表
tyne: index 说明用主键rental_id的索引排序的


image.png

顺序反了一下就不行了

rentail_date>'2005-05-09'使其用不到索引排序

因为rentail_date是联合索引的第一列 这么一用后面的索引就死去效用了

normal:表示普通索引
unique:表示唯一的,不允许重复的索引,如果该字段信息保证不会重复例如身份证号用作索引时,可设置为unique
full textl: 表示 全文搜索的索引。 FULLTEXT 用于搜索很长一篇文章的时候,效果最好。用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以。
总结,索引的类别由建立索引的字段内容特性来决定,通常normal最常见。
cuidiwhere 的CSDN 博客

不支持hash的引擎时 betree模拟hash索引优化查询

title太长了不能直接betree

ALTER TABLE film add title_md5 varchar(32);
update film set title_md5=md5(title);
create index idx_md5 on film(title_md5);

2个上都过滤避免hash冲突

必须先md5列把可能的数据返回到内存中,再筛选

innodb行锁是说更新时 只锁定需要的行,过滤掉了不需要的行时才会有效,如果不能过滤掉行,就会锁定所有行,再在内存中用where条件过滤,索引可以减少被锁定的行数,因为加快了处理速度 锁的释放速度也会变快



drop index idx_actor_last_name on actor;

一个查询中开启事务 查询 加排他锁 不提交

第二个查询虽然明明查的不是同一行 还是被阻塞,说明另一个查询其实锁全表了

如果索引不删 不会这样

该删的索引

重复索引,主键本来就是非空唯一索引

第一行保留第二个,第二个行改成index(a)

查看可删的索引
pt-duplicate-key-checker h=127.0.0.1

没被使用的索引

可以看到索引使用次数

要定期维护表和索引的碎片,更新索引统计信息

analyze table table_name更新索引统计信息MyISAM会锁全表,innodb只是估值
optimize table table_name维护碎片 都会锁全表

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 225,124评论 6 523
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,453评论 3 404
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,386评论 0 368
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,136评论 1 301
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,142评论 6 400
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,593评论 1 315
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,958评论 3 429
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,944评论 0 279
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,477评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,512评论 3 346
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,639评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,227评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,971评论 3 340
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,397评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,550评论 1 277
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,203评论 3 381
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,713评论 2 366

推荐阅读更多精彩内容