1 从逻辑角度划分类 索引本质上是表字段的有序子集,其每个记录项指向相应的表记录。MySQL共有4类索引:
1.1 主键索引 主键索引用于根据主键自身的唯一性来唯一标识每条记录。
因此,该键必须是该记录所表示实体唯一拥有的值,或者是数据库生成的唯一值,例如,自增整数。
示例: 设置id作为自增主键索引.
1 2 3 4 5 6 7 create table `bookmarks` ( `id` int unsigned not null auto_increment comment '主键id', `name` varchar(75) not null default '' comment '名称', `url` varchar(200) not null default '' comment 'URL', `description` mediumtext not null comment '描述', primary key(`id`) ) engine=InnoDB default charset=utf8mb4 comment='书签表';
注:每个表只能有一个自增字段,且该字段必须为主键,为主键的字段不能包含null值,即使没有显式申明为not null, MySQL也会自动赋予此特性.
1.2 唯一索引 与主键索引一样,唯一索引可以预防哪个创建重复的值。但是,与之不同之处在于每个表只能有一个主键索引,但可以有多个唯一索引.可以为null值.
示例:设置name和url作为唯一联合索引
1 2 3 4 5 6 7 8 create table `bookmarks_v1` ( `id` int unsigned not null auto_increment comment '主键id', `name` varchar(75) not null default '' comment '名称', `url` varchar(200) not null default '' comment 'URL', `description` mediumtext not null comment '描述', primary key (`id`), unique key `name_url` (`name`,`url`) ) engine=InnoDB default charset=utf8mb4 comment='书签表';
1.3 普通索引 普通索引可以分为单列普通索引
和联合普通索引
.
1.3.1 单列普通索引 若表中的某个列将成为大量选择查询的焦点,就应当使用单列普通索引。
示例:设置email为唯一索引,姓氏为单例普通索引。
1 2 3 4 5 6 7 8 9 create table employees( `id` int unsigned not null auto_increment comment '主键id', `firstname` varchar(100) not null default '' comment '名称', `lastname` varchar(100) not null default '' comment '姓氏', `email` varchar(100) not null default '' comment '电子邮箱', primary key (`id`), unique key `idx_email` (`email`), key `idx_lastname` (`lastname`) ) engine=InnoDB default charset=utf8mb4 comment='员工信息表';
1.3.2 多列普通索引(联合索引) 若在查询中,经常会使用多列一起使用,则可使用联合索引,MySQL的联合索引方法基于最左前缀的策略.
假设为列A、B、C添加联合索引,则使用下列组合可以提高涉及的查询性能:
示例:
1 2 3 4 5 6 7 8 9 create table employees_v1( `id` int unsigned not null auto_increment comment '主键id', `firstname` varchar(100) not null default '' comment '名称', `lastname` varchar(100) not null default '' comment '姓氏', `email` varchar(100) not null default '' comment '电子邮箱', primary key (`id`), unique key `idx_email` (`email`), key `idx_lastname_firstname` (`lastname`, `firstname`) ) engine=InnoDB default charset=utf8mb4 comment='员工信息表';
1.4 全文索引 全文索引提供了一种高效的方法来搜索存储为char
,varchar
或者text
数据类型的文本。
示例:在description
字段上添加全文索引。
1 2 3 4 5 6 7 8 create table `bookmarks_v2` ( `id` int unsigned not null auto_increment comment '主键id', `name` varchar(75) not null default '' comment '名称', `url` varchar(200) not null default '' comment 'URL', `description` mediumtext not null comment '描述', primary key(`id`), fulltext key `idx_description`(`description`) ) engine=InnoDB default charset=utf8mb4 comment='书签表';
基于全文索引获取数据时,select查询使用两个特殊的MySQL函数MATCH()
和AGAINST()
。利用这两个函数,可以针对全文索引执行自然语言搜索,如下所示:
1 2 3 4 5 6 7 insert into bookmarks_v2 (name,url,description) values ("Python", "www.python.org", "The official Python Web site"), ("MySQL manuel", "http://dev.mysql.com/doc", "The MySQL reference manual"), ("Apache site", "http://httpd.apache.org", "Includes Apache 2 manual"), ("PHP Hypertext", "www.php.net", "The official PHP Web site"), ("Apache Week", "www.apacheweek.com", "Offers a dedicated Apache 2 section");
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 mysql> select name,url FROM bookmarks_v2 where match(description) against('Apache 2'); +-------------+-------------------------+ | name | url | +-------------+-------------------------+ | Apache site | http://httpd.apache.org | | Apache Week | www.apacheweek.com | +-------------+-------------------------+ 2 rows in set (0.07 sec) mysql> select match(description) against('Apache 2') from bookmarks_v2; +----------------------------------------+ | match(description) against('Apache 2') | +----------------------------------------+ | 0 | | 0 | | 0.15835624933242798 | | 0 | | 0.15835624933242798 | +----------------------------------------+ 5 rows in set (0.05 sec)
该查询列出在description中出现了”Apache”的记录,以相关性从高到底的顺序排序。(其中”2”由于长度过短,因此被忽略了).
当MATCH()
用于WHERE
子句时,相关性按照返回的记录与搜索的字符串的匹配程度来定义。
MATCH和AGAINST函数也可以放在查询体中,返回匹配记录的加权列表,分数越高,相关性就越大 .
2 索引的创建方式 创建索引的方式有两种:
2.1 alter table方式创建索引 1 2 3 4 5 6 7 8 9 10 # 添加主键索引 alter table `table_name` add primary key(`column`) # 添加唯一索引 alter table `table_name` add unique key (`column`) # 添加普通单列索引 alter table `table_name` add key index_name (`column`) # 添加普通联合索引 alter table `table_name` add key index_name(`column1`, `column2`,...) # 添加全文索引 alter table `table_name` add fulltext (`column`)
2.2 create table方式创建索引 见本文第一小结.
3 索引的触发 Mysql只会对<、<=、 =、 >=、 >、 between、in
以及不以通配符%和_开头的like
有效。
示例:
1 2 3 4 # 不会用到索引 select * from bookmarks where description like '%The'; # 会用到索引 select * from bookmarks where description like 'The%';
4 索引的优缺点 优点 :提高查询的效率.
缺点 :
降低更新表的速度,比如对表进行INSERT, UPDATE,DELETE。因为在更新表时,MYSQL不仅要保存数据。还要保存一些索引文件。
建立索引会占用磁盘空间,若在一个很大的表上创建了多种组合的索引,索引文件将膨胀得很快。
5 按物理存储角度分类 从物理存储角度划分,索引可以分为:
6 按数据结构的角度划分 从数据结构角度划分,索引可分为以下几种:
B+树索引
Hash索引
Fulltext索引
R-Tree索引
可参考另一片笔记:【索引】高性能MySQL_第三版-创建高性能索引.note
参考资料 PHP与MySQL程序设计 第四版 P532
MYSQL的索引类型:PRIMARY, INDEX,UNIQUE,FULLTEXT,SPAIAL 有什么区别?各适用于什么场合?
面试官:谈谈你对mysql索引的认识?