Innodb 索引

聚集索引

聚集索引又称为聚簇索引,聚集索引就是按照每张表的主键构造一颗 B+ 树,同时叶子节点中存放的即是整张表的行记录数,也称为数据页。这种特性决定了索引组织表中的数据也是索引的一部分;

注意:
由于磁盘上的数据页只能按照一个顺序进行存储,因此每张表只能按照一个 B+ 树进行排序,所以每张表最多只能有一个聚集索引。

辅助索引

辅助索引也称为非聚集索引,叶子结点并不包含行记录的全部数据,而是一个指向该行数据的聚集索引的书签。

联合索引

联合索引指对表上的多列进行索引

image.png

联合索引的意思就相当于数组按照多个字段进行排序,如:a,b 两列创建联合索引,那么叶子节点上的数据先按照 a 列值进行排序,如果 a 列值相等在按照 b 列值进行排序,因此也可以理解联合索引在什么情况下会失效。

注意:联合索引的使用及失效情况

// 1、创建一个三列的联合索引
create index in_a_b_c on joint(a, b, c);

// 2、推荐使用方式
mysql> explain select * from joint where a = 'aa' and b = 'bb' and c = 'cc';
+----+-------------+-------+------------+------+---------------+----------+---------+-------------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key      | key_len | ref               | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-------------------+------+----------+-------+
|  1 | SIMPLE      | joint | NULL       | ref  | in_a_b_c      | in_a_b_c | 414     | const,const,const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+----------+---------+-------------------+------+----------+-------+
1 row in set, 1 warning (0.02 sec)

// 3、调换索引列顺序后也是可以生效的
mysql> explain select * from joint where b = 'bb' and c = 'cc' and a = 'aa';
+----+-------------+-------+------------+------+---------------+----------+---------+-------------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key      | key_len | ref               | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-------------------+------+----------+-------+
|  1 | SIMPLE      | joint | NULL       | ref  | in_a_b_c      | in_a_b_c | 414     | const,const,const |   12 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+----------+---------+-------------------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

// 或者条件中缺少第二或第三列,联合索引也可以生效
mysql> explain select * from joint where c = 'cc' and a = 'aa';
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key      | key_len | ref   | rows | filtered | Extra                 |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-----------------------+
|  1 | SIMPLE      | joint | NULL       | ref  | in_a_b_c      | in_a_b_c | 138     | const |   12 |    10.00 | Using index condition |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

// 4、索引失效
mysql> explain select * from joint where b = 'bb' and c = 'cc';
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
|  1 | SIMPLE      | joint | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 986832 |     1.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

根据联合索引实现方式,很容易理解为什么第三种查询索引会失效。因为联合索引首先是按照 a 列进行排序的,b 列和 c 列此时是散列放置的,如果只是按照 b 和 c 来查询,索引是无法起作用的;

覆盖索引

覆盖索引是指从辅助索引中就可以查到记录,而不需要查询聚集索引中的记录。(从索引文件中即可查到结果,不需要查询原表数据)

// 联合索引如果只使用 b 当做条件查询所有列值时,索引是无法起作用的,但是如果是统计或者只查询 b 列值,联合索引就可起作用
mysql> explain select count(*) from joint where b = 'bb';
+----+-------------+-------+------------+-------+---------------+----------+---------+------+--------+----------+--------------------------+
| id | select_type | table | partitions | type  | possible_keys | key      | key_len | ref  | rows   | filtered | Extra                    |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+--------+----------+--------------------------+
|  1 | SIMPLE      | joint | NULL       | index | NULL          | in_a_b_c | 414     | NULL | 986832 |    33.33 | Using where; Using index |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+--------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)


// 1、创建一个普通索引
create index in_d on joint(d);
// 2、只查询索引列数据
mysql> explain select d from joint;
+----+-------------+-------+------------+-------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key  | key_len | ref  | rows   | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+------+---------+------+--------+----------+-------------+
|  1 | SIMPLE      | joint | NULL       | index | NULL          | in_d | 138     | NULL | 986832 |   100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

虽然 possible_keys 显示为空,但是实际上是用到了索引的,并且 Extra 的值为 Using index,表示使用了覆盖索引。索引文件通常比数据文件要小,因此直接从索引文件中查询数据会比从数据文件中差数据要快。

哈希算法

Innodb 支持哈希索引,但是不能通过人为进行干预,是数据库自己创建的,称为自适应哈希。

全文索引

Mysql 5.6 之前 Innodb 不支持全文索引,5.6版本之后支持全文索引。

全文索引是通过倒叙排序来实现的,它的辅助表中存储了单词与单词自身在一个或者多个文档中所在位置之间的映射。Innodb 采用的是 full inverted index 的形式来存储映射关系,即{单词,(单词所在文档 id,文档具体位置)}

// 1、创建索引
mysql> create fulltext index ft_index on demo_text(text);
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> create fulltext index ft_index on demo_text(text) with parser ngram;
Query OK, 0 rows affected (0.12 sec)
Records: 0  Duplicates: 0  Warnings: 0

// 2、使用索引
mysql> select * from demo_text where match(text) against ('one');
+----+---------------+
| id | text          |
+----+---------------+
|  1 | some one here |
|  2 | one two three |
+----+---------------+
2 rows in set (0.00 sec)

// 3、查询每个词的映射
mysql> set global innodb_ft_aux_table = 'myproject/demo_text';
Query OK, 0 rows affected (0.00 sec)
mysql> select * from information_schema.innodb_ft_index_table;
+-------+--------------+-------------+-----------+--------+----------+
| WORD  | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION |
+-------+--------------+-------------+-----------+--------+----------+
| four  |            5 |           5 |         1 |      5 |        9 |
| here  |            3 |           5 |         2 |      3 |        9 |
| here  |            3 |           5 |         2 |      5 |        4 |
| one   |            3 |           4 |         2 |      3 |        5 |
| one   |            3 |           4 |         2 |      4 |        0 |
| some  |            3 |           3 |         1 |      3 |        0 |
| three |            4 |           4 |         1 |      4 |        8 |
| two   |            4 |           5 |         2 |      4 |        4 |
| two   |            4 |           5 |         2 |      5 |        0 |
+-------+--------------+-------------+-----------+--------+----------+
9 rows in set (0.02 sec)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • 1. InnoDB存储引擎索引概述 InnoDB支持以下常见索引: B+树索引 全文索引 哈希索引 ​  Inno...
    爱健身的兔子阅读 600评论 0 0
  • InnoDB存储引擎支持事务,是一个通用的、平衡了高可用与高性能的存储引擎。它的设计目标主要面向在线事务处理(OL...
    Justlearn阅读 2,953评论 2 13
  • 四、索引 mysql支持的常见索引:B+,全文、hash 1.B+树索引 B+树索引可以分为聚簇索引和非聚簇索引。...
    一只小星_阅读 389评论 0 0
  • 1.1 B+ 树索引 B+ 索引在数据库的一个特点是高扇出性,因此树的高度一般都在 2 ~ 4 层。 数据库中的 ...
    A_Zeee阅读 111评论 0 0
  • 夜莺2517阅读 127,709评论 1 9