MySQL索引

2019-07-26  本文已影响0人  王王王王王景

1、前言

索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索引包含多个列。实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。
过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件。

索引类型:
(1)普通索引
(2)唯一索引
(3)主键索引
(4)组合索引
(5)全文索引

1.1查看索引

show index from myable;

1.2常见添加索引的方式

# 普通索引
alter table mysql add index [index_name] (column_name);

# 唯一索引
# 索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一
alter table mytable add unique [index_name] (column_name);

# 主键索引
alter table mytable add primary key [index_name] (column_name);

# 组合索引
alter table mytable add unique [index_name] (column_name1, column_name2, column_name3);

# 全文索引
alter table mytable add fulltext [index_name] (column_name);

2、多列索引(组合索引)

https://www.cnblogs.com/duanxz/p/5244737.html
https://www.cnblogs.com/wxgblogs/p/5743895.html

在一个b树上面建立关于多列的索引,一次通过比较列的属性值来寻找合适的node;
为了提高搜索效率,我们需要考虑运用多列mysql数据库索引。如果为firstname、lastname和age这三个列创建一个多列索引,MySQL只需一次检索就能够找出正确的结果!下面是创建这个复合索引的SQL命令:

ALTER TABLE people ADD INDEX fname_lname_age (firstname,lastname,age);

由于索引文件以B-树格式保存,MySQL能够立即转到合适的firstname,然后再转到合适的lastname,最后转到合适的age。在没有扫描数据文件任何一个记录的情况下,MySQL就正确地找出了搜索的目标记录!

那么,如果在firstname、lastname、age这三个列上分别创建单列索引,效果是否和创建一个firstname、lastname、age的多列MySQL数据库索引一样呢?答案是否定的,两者完全不同。当我们执行查询的时候,MySQL只能使用一个索引。如果你有三个单列的MySQL数据库索引,MySQL会试图选择一个限制最严格的索引。但是,即使是限制最严格的单列索引,它的限制能力也肯定远远低于firstname、lastname、age这三个列上的多列索引。

索引是快速搜索的关键。MySQL索引的建立对于MySQL的高效运行是很重要的。

3、全文索引

全文索引是用于检索字段中是否包含或不包含指定的关键字,有点像搜索引擎的功能,其内部的索引结构采用的是与搜索引擎相同的倒排索引结构,其原理是对字段中的文本进行分词,然后为每一个出现的单词记录一个索引项,这个索引项中保存了所有出现过该单词的记录的信息,也就是说在索引中找到这个单词后,就知道哪些记录的字段中包含这个单词了。因此适合用大文本字段的查找。

3.1创建全文索引

该文章讲解了全文索引的一些细节:MySQL 5.7 中文全文检索使用教程

# 在创建表的时候
CREATE TABLE article (
    id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
    title VARCHAR(200),
    content TEXT,
    FULLTEXT (title, content) --在title和content列上创建全文索引
);

# 修改表的结构添加全文索引
ALTER TABLE article ADD FULLTEXT INDEX fulltext_article (title, content)

3.2全文索引的使用

SELECT * FROM article WHERE MATCH(title, content) AGAINST('查询字符串')

match 匹配
against 与...相比

3.3全文检索模式

常用的全文检索模式有两种:
1、自然语言模式(NATURAL LANGUAGE MODE) ,
自然语言模式是MySQL 默认的全文检索模式。自然语言模式不能使用操作符,不能指定关键词必须出现或者必须不能出现等复杂查询。

SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('一路 一带' IN NATURAL LANGUAGE MODE);

// 不指定模式,默认使用自然语言模式
SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('一路 一带');

2、BOOLEAN模式(BOOLEAN MODE)
BOOLEAN模式可以使用操作符,可以支持指定关键词必须出现或者必须不能出现或者关键词的权重高还是低等复杂查询。

// 必须包含"腾讯"
SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('+腾讯' IN BOOLEAN MODE);
// 必须包含"腾讯",但是不能包含"通讯工具"
SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('+腾讯 -通讯工具' IN BOOLEAN MODE);

下面的例子演示了BOOLEAN模式下运算符的使用方式:

'apple banana' 
无操作符,表示或,要么包含apple,要么包含banana

'+apple +juice'
必须同时包含两个词

'+apple macintosh'
必须包含apple,但是如果也包含macintosh的话,相关性会更高。

'+apple -macintosh'
必须包含apple,同时不能包含macintosh。

'+apple ~macintosh'
必须包含apple,但是如果也包含macintosh的话,相关性要比不包含macintosh的记录低。

'+apple +(>juice <pie)'
查询必须包含apple和juice或者apple和pie的记录,但是apple juice的相关性要比apple pie高。

'apple*'
查询包含以apple开头的单词的记录,如apple、apples、applet。

'"some words"'
使用双引号把要搜素的词括起来,效果类似于like '%some words%',
例如“some words of wisdom”会被匹配到,而“some noise words”就不会被匹配。

注意:

只能在类型为CHAR、VARCHAR或者TEXT的字段上创建全文索引。
全文索引只支持InnoDB和MyISAM引擎。
MATCH (columnName) AGAINST ('keywords')。MATCH()函数使用的字段名,必须要与创建全文索引时指定的字段名一致。如上面的示例,MATCH (title,body)使用的字段名与全文索引ft_articles(title,body)定义的字段名一致。如果要对title或者body字段分别进行查询,就需要在title和body字段上分别创建新的全文索引。
MATCH()函数使用的字段名只能是同一个表的字段,因为全文索引不能够跨多个表进行检索。
如果要导入大数据集,使用先导入数据再在表上创建全文索引的方式要比先在表上创建全文索引再导入数据的方式快很多,所以全文索引是很影响TPS的。

组合索引和全文索引的使用场景?
答:组合索引的索引值比对是遵循从左向右的比对(字符串的比对),但是全文索引是先将索引值进行分词,然后再一一的进行比对;组合查询适用于比较小的索引值,全文索引适用于一些保存大量文本的数据值的比对(比如文章内容);

4.普通索引

这是最基本的索引,它没有任何限制。它有以下几种创建方式:

创建索引

create index indexname on mytable(username(length));

这里的username是列名,是varchar类型的,length的设定应该是选择了username中长度为length的部分;
如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length。

4.1修改表结构

alter table mytable add index index_name(column_name);

4.2创建表的时候直接指定

create table mytable (
  id int unsigned primary_key auto_increment ,
  username varchar(16) not null,
  index [username_index] (username(length))
);

4.3删除索引

# 两种方式
drop index  [index_name] on mytable;

alter table mytable drop index column_name;

5.唯一索引

它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:

create unique index  index_name on mytable(username(length));

alter table mytable add unique index_name (column_name);
上一篇下一篇

猜你喜欢

热点阅读