SQL 索引

原文链接1
原文链接2

什么是索引

索引的目的在于提高查询效率。

一 般的应用系统,读写比例在10:1 左右 ,而且插入操作的一般的更新操作很少出现性能问题,在生产环境中,我们遇到的更多的,也是最容易出问题的,还是一些复杂的查询操作。而查询中,索引则显示得特别重要。

索引在 MySQL 中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其当表中的数据特别大时,索引以俞发重要。

磁盘 IO 与预读

磁盘 IO是非常高昂的操作,计算机操作系统做了一些优化,当一次 IO时,不光把当前磁盘地址的数据,而是把相邻的数据也都读取到内存缓冲区内。局部预读性原理告诉我们,当计算机访问一个地址的数据的时候,与其相邻的数据也会很快被访问到。

每一次IO读取的数据我们称之为一页(page)。具体一页有多大数据跟操作系统有关,一般为4k或8k,也就是我们读取一页内的数据时候,实际上才发生了一次IO,这个理论对于索引的数据结构设计非常有帮助。

索引的数据结构

数据结构要求,每次查找数据时把磁盘IO次数控制在一个很小的数量级,最好是常数数量级。 B+ 树应运而生。

示例如图
  1. 浅蓝色的块称之为一个磁盘块,每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示)。
  2. 如磁盘块1包含数据项17和35,包含指针P1、P2、P3,P1表示小于17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块。
  3. 真实的数据存在于叶子节点即3、5、9、10、13、15、28、29、36、60、75、79、90、99。非叶子节点只不存储真实的数据,只存储指引搜索方向的数据项,如17、35并不真实存在于数据表中。
B+树的查找过程

查找数据项29:
首先会把磁盘块1由磁盘加载到内存,此时发生一次IO,在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针,内存时间因为非常短(相比磁盘的IO)可以忽略不计,通过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次IO,29在26和30之间,锁定磁盘块3的P2指针,通过指针加载磁盘块8到内存,发生第三次IO,同时内存中做二分查找找到29,结束查询,总计三次IO。

3层的b+树可以表示上百万的数据,如果上百万的数据查找只需要三次IO,性能提高将是巨大的,如果没有索引,每个数据项都要发生一次IO,那么总共需要百万次的IO,显然成本非常非常高。

B+ 树性质
  1. 索引字段要尽量的小
  2. 索引的最左匹配特性(即从左往右匹配)
MySQL 索引分类
  1. 普通索引 index: 加速查找
  2. 唯一索引
    主键索引:primary key :加速查找+约束(不为空且唯一)
    唯一索引:unique: 加速查找+约束 (唯一)
  3. 联合索引
    primary key(id,name):联合主键索引
    unique(id,name):联合唯一索引
    index(id,name):联合普通索引
  4. 全文索引fulltext : 用于搜索很长一篇文章的时候,效果最好。
  5. 空间索引spatial : 几乎不用
创建/删除索引

key 列
PRI 主键索引
MUL 辅助索引
UNI 唯一索引
在创建表时就创建(需要注意的几点)

    create table s1(
    id int ,  
    # 可以在这加primary key
    # id int index不可以这样加索引,因为index只是索引,没有约束一说,不能像主键,还有唯一约束一样,在定义字段的时候加索引
    name char(20),
    age int,
    email varchar(30)
    index(id) #可以这样加
    #primary key(id) #也可以在这加
    );

在创建表后在创建

    create index name on s1(name); #添加普通索引
    create unique age on s1(age);#添加唯一索引
    create index name on s1(id,name); #添加普通联合索引
    alter table s1 add primary key(id); #添加住建索引,也就是给id字段增加一个主键约束

    ALTER TABLE 表名 ADD INDEX idx_索引名(索引列); #建立指定列的单列索引
    ALTER TABLE 表名 ADD INDEX idx_索引名(索引列(n)); #建立指定列的前缀索引(n为前缀长度)
    ALTER TABLE 表名 ADD INDEX idx_索引名(索引列1,索引列2,...); #建立多列的联合索引

删除索引

    drop index id on s1;
    drop index name on s1; #删除普通索引
    drop index age on s1; #删除唯一索引,就和普通索引一样,不用在index前加unique来删,直接就可以删了
    alter table s1 drop primary key; #删除主键(因为它添加的时候是按照alter来增加的,那么我们也用alter来删)
索引使用
  1. 覆盖索引
select * from s1 where id=123; 

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

推荐阅读更多精彩内容