索引
索引被用来快速找出想要的数据,提高性能。
没有索引,数据库不得不从第一条记录开始搜索,效率非常低。
MYISAM与INNODE都使用B-Tree作为索引结构
索引可分单列索引(主键索引,唯一索引,普通索引)和组合索引
- 单列索引:一个索引只包含一个列,一个表可以有多个单列索引
- 组合索引:一个组合索引包含两个或两个以上的列
主键,unique都会自动添加索引
Mysql默认配置索引的词长度是4
1、单列索引
1.1、普通索引
创建索引
- 格式1
alter table 表名 add index 索引名(字段名); - 格式2
create index 索引名 on 表名(字段名);
alter table emp2 add index ename_index(ename); #格式1
create index ename_index on emp2(ename); #格式2
show index from emp2; #查看索引
使用索引查询
在selct前面加explain,如果看到type!=all,则说明使用了索引
#查出名字是C开头的记录
MariaDB> explain select * from emp2 where ename like 'C%';
+------+-------------+-------+-------+---------------+-------------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+-------------+---------+------+------+-----------------------+
| 1 | SIMPLE | emp2 | range | ename_index | ename_index | 33 | NULL | 1 | Using index condition |
+------+-------------+-------+-------+---------------+-------------+---------+------+------+-----------------------+
删除索引
格式1
drop index 索引名 on 表名;格式2
alter table 表名 drop index 索引名;格式3(只针对pk)
alter table 表名 drop primary key;
drop index ename_index on emp2; #格式1
alter table emp2 drop index ename_index; #格式2
alter table emp2 drop primary key; #删除主键
1.2、唯一索引
与普通索引的区别是,要求所有此字段所有数据都是唯一的,但允许有空值
创建索引
格式1
create unique index 索引名 on 表名(字段名);格式2
alter table 表名 add unique(字段名);
create unique index ename_unique on emp2(ename); #格式1
alter table emp2 add unique(ename); #格式2
1.3、主键索引
即主键约束,要求字段数据唯一且不为空,按照约束的操作方式进行操作即可
2、组合索引
组合索引是一个索引名,包含了多个字段
创建索引
格式
create index 索引名 on 表名(字段1,字段2,字段3...);
create index job_hiredate_sal_index on emp2(job,hiredate,sal);
建立如上组合索引(job_hiredate_sal_index),实际是包含3个索引:(job),(job,hiredate),(job,hiredate,sal)
索引遵守“最左前缀”原则
不按索引最左列开始查询
index(job,hiredate,sal),where hiredate='1980-12-17'不会使用索引,where hiredate='1980-06-07' and sal=800不会使用索引查询中某个列有范围查询,则其右侧无法用到索引查询
where job='clerk' and hiredate like '1980%' and sal=800,该查询只会使用索引的前两列不能跳过牟广丰字段进行查询,这样不会用到索引
where job>'clerk' and hiredate='1980-12-17' and sal=800;第一个字段出现范围符号查询,那么不会用到索引查询
3、全文检索
3.1基础全文所搜
全文检索fulltext的要求
- 存储引擎必须是MyISAM或者mysql5.6以上的InnoDB
- 字段类型必须是char,varchar,text
由于Mysql默认配置的索引词长是4,所以要支持中文单字的话,首先要修改ft_min_word_len
参数
如果是2可能会出现搜索不到数字或者英文的情况,可以改为1
,一般是/etc/my.cnf
,如果没找到
,可以先查找find / -name 'my.cnf'
ft_min_word_len = 1
创建全文索引
格式
create fulltext index 索引名 on 表名(字段名1,字段名2...);
使用全文索引
create fulltext index job_fulltext on emp2(job);
explain select * from emp2 where match(job) against('clerk');
与like
区别,对于数据量级到达十万百万的级别,fulltext
性能明显优于like
,另外对于搜索能够明确控制,并智能 化给出结果
全文搜索一个重要部分就是对结果排序
MariaDB> select job,match(job) against('clerk') as rank from emp2;
+-----------+--------------------+
| job | rank |
+-----------+--------------------+
| CLERK | 0.2960100471973419 |
| SALESMAN | 0 |
| SALESMAN | 0 |
| MANAGER | 0 |
| SALESMAN | 0 |
| MANAGER | 0 |
| MANAGER | 0 |
| ANALYST | 0 |
| PRESIDENT | 0 |
| SALESMAN | 0 |
| CLERK | 0.2960100471973419 |
| CLERK | 0.2960100471973419 |
| ANALYST | 0 |
| CLERK | 0.2960100471973419 |
+-----------+--------------------+
#上述有个rank等级,全文搜索根据行中词的数目、唯一词的数目、整个索引中词的总数以及包含该词的行的数目来计算等级。等级高的排在结果前面
3.2、全文搜索的查询扩展
格式
select 字段 from 表名 where match(字段) against('搜索字符串' with query expansion);
机制:
- 首先,进行一个基本的全文本搜索,找出与搜索条件匹配的所有行
- 其次,Mysql检查这些匹配行并选择所有有用的词
- 再次,Mysql再次进行全文本搜索,这次不仅使用原来的条件,而且还使用所有有用的词
3.3、布尔文本搜索
机制:
- 要匹配的词
- 要排斥的词(如果某行包含这个词,则不返回该行,即使它包含其他指定的词)
- 排列提示(指定某些词比其他词更重要,更重要的词等级更高)
- 表达式分组
- 另外一些内容
布尔方式即使没有定义fulltext索引也可使用,但这是一种非常缓慢的操作
格式
select 字段 from 表名 where match(字段) against('需要的词 其他条件的词' in boolean mode);
全文本布尔操作符
布尔操作符 | 说明 |
---|---|
+ | 包含,词必须存在 |
- | 排除,词必须不出现 |
> | 包含,而且增加等级值 |
< | 包含,且减少等级值 |
() | 把词组成子表达式(允许这些子表达式作为一个组被包含、排除、排列等) |
~ | 取消一个词的排序值 |
* | 词尾的通配符 |
"" | 定义一个短语(与单个词的列表不样,它匹配整个短语以便包含或排除这个短语) |
4、索引使用分析
适用场景
- 表中该字段中的数据量庞大
- 经常被检索,经常出现在where子句中的字段
- 经常被DML操作的字段不建议添加索引
优点
- 大大提高检索数据的性能效率
- 在表连接的连接条件,可以加速表与表直接的相连
- 在分组和排序字句进行数据检索,可以减少查询时间中 分组 和 排序时所消耗的时间(数据库的记录会重新排序)
缺点
- 创建与维护索引会消耗时间,并随着数据量的增加而增加
- 索引也会占用物理存储空间
- 在进行DML操作的时候,索引也要动态的维护,会降低数据的维护速度