MySQL 拾穗者 一 索引

概述

用来加快查询的技术很多,其中最重要的是索引
如果不适用索引,MYSQL必须从第一条记录开始然后读完整个表直到找出相关的行

索引的本质

官方的定义:索引(Index)是帮助MySQL高效获取数据的数据结构
本质:索引是数据结构

引用index的必要性

常见的查询算法包含linear search(顺序查询),binary search(二分查找),binary tree search(二叉树查找)
每种查找算法只能应用于特定的数据结构上,二分查找要求检索的数据有序,二叉树查找应用于二叉查找######树上
数据本身的组织结构不可能完全满足各种数据结构

存储分类

索引是在mysql的存储引擎层中实现的,不是在服务层实现,每种存储引擎的索引不一定完全相同,不同的存储引擎支持不同的索引类型
索引 MyISAM引擎 InnoDB索引 Memory引擎
B-Tree Yes Yes Yes
HASH Yes
R-Tree Yes
Full-text

四种索引
B-Tree索引:最常见的索引
HASH索引:使用场景简单
R-Tree索引:空间索引,主要用于地理空间的数据类型
Full-text索引:全文索引,从MYSQL5.6开始提供全文索引支持
说明

Mysql目前不支持函数索引,
但是能对列的前面的某一部分进行索引,例如可以只取某列的前面的几个字符进行索引

create index idx_title on table (title(10))

但是前缀索引在排序order by ,分组group by时候无法使用

B-TREE索引类型

普通索引,没有唯一性之类的限制,

创建索引:create index 索引名 on table_name(column1,column2); 修改表:alter table table_name add index 索引名(column1,column2); 创建表时指定索引:create table table_name ([...], index 索引名(column1,column2,...));

unique索引,表示唯一的,

创建索引:create unique index 索引名 on table_name(column1,column2); 修改表:alter table table_name add unique index 索引名(column1,column2); 创建表时指定索引:create table table_name ([...], unique index 索引名(column1,column2,...));

主键,主键是一种唯一性的索引

修改表:alter table table_name add primary key(column1); 创建表时指定主键:create table table_name ([...], primary key(column1));


删除,查看索引

删除索引语法如下:

drop index index_name on table_name; alter table table_name drop index index_name; alter table table_name drop primary key

如果从表中删除了某列,索引将会受到影响,
如果删除了某列,该列会从索引中删除
如果删除了组成索引的所有列,整个索引将会被删除
查看索引语法如下:

show index from table_name; show keys from table_name


索引选择原则

较频繁的作为查询条件的字段应该创建索引
唯一性太差的字段不适合单独创建索引,即使频繁的作为查询条件
更新非常频繁的字段不适合创建索引
不会出现在where字句中的字段不该创建索引

索引选择原则补充

1选择在哪个列上面创建索引是非常重要的,

可以考虑使用索引的列主要有两种类型的列:where 字句中出现的列,在join字句中出现的列,而不是在select 关键字后选择列表的列

2 索引的基数越大,索引的效果越好,假如使用性别来进行区分行,只有两种选择,对此字段进行索引没有太多用处
3 使用短索引,如果对字符串列进行索引,应该指定一个前缀长度,可以节省大量索引空间,提升查询速度

例如,有一个char(200)的列,如果前面的10个或者20个字符内,多数值是唯一的,可以不对整个列进行索引,对前面的字符进行索引可以节省出大量的索引空间,也可以提升查询的速度,原因是:较少的字符索引涉及的磁盘IO较少,短短的值比较容易IO,对于较短的键值,高速缓存中的块能够容纳更多的键值,mysql在内存中可以容纳更多的值,这样就增加了找到行而不用读取索引中更多的块的可能性

4 利用最左前缀

mysql会一直向右匹配直到遇到范围查询,停止匹配

5 =和in 可以乱序

比如a=1 and b=2 and c=3建立(a,b,c)索引可以是任意顺序,mysql的查询优化器可以将索引优化为可以识别的形式

6索引列不能参加运算

比如下面的索引from _unixtime(create_time) = '2016-05-19';就不能使用索引,因为当数据表中的数值都应用函数才能比较,成本太高,可以变成索引 create_time = unix_timestamp('2016-05-19');使用

7 尽量的扩展索引,不要新建索引

比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可


两种情况不建议使用索引

1表的记录比较少,例如只有一两千条数据,没有必要创建索引,直接查询做全表扫面就可以了

多少条记录可以考虑创建索引,个人经验是2000条

2 索引的选择性较低时候,

index Selectivity = Cardinality / #T, 索引的选择性(index selecivity),不重复的索引值(也称为基数,cardinality),表的记录数(#T), 选择性的取值范围是(0,1],选择性较高的索引的价值较高,假设有一个表为employees.titles,如果表中存在字段title,可以通过公式计算出它的选择性, select count(distinct(title))/count(*) as selectivity from employees.titles;

mysql只对下面的操作符才使用索引

< <= = > >= between in 和某些时候的like (不以通配符%或者_开头的情形)

不要过度索引,只保持所需要的索引
在修改表的时候,索引也必须进行更新,有时候可能需要重构,索引越多,可能使用的时间会越多

引用
人云思云,mysql索引
美团点评技术团队,MySQL索引原理及慢查询优化

你可能感兴趣的:(MySQL 拾穗者 一 索引)