前言:
索引对于数据库的意义重大。尤其是对于海量数据的大表。有索引和没有索引的速度就像法拉利和三轮车。那么有这么好的工具,学习索引和使用索引那就变成了理所当然的事情了。下面我就以MYSQL数据库为例。介绍下索引的三个方面
什么是索引?为什么要用索引?
索引其实也是一张表。它存储的是索引的值和对应表中的物理位置。他能帮助数据库快速的找到想要找的数据。不同的索引只是存储的数据的特性不同。不同的索引引擎也只是存储和搜索策略的不同。本质上还是一张表,会占磁盘空间或者内存空间。
那么为什么要用索引呢?这个问题就像是在问用汉语词典的时候为什么要先查音节表或者部首检字表?为什么要这么做呢?
因为快!
没有索引的表用起来就像是翻开汉语字典一页页的找你想找的字。效率太慢。
所以索引是我必须要使用的工具
(也有不适合使用索引的场景。后面会讲)
怎么使用索引
使用索引之前,我们需要了解,MYSQL 有哪些索引
常见的索引类型有:主键索引 唯一索引 普通索引 全文索引 组合索引
- 主键索引:即主索引,根据主键pk_clolum(length)建立索引,不允许重复,不允许空值
ALTER TABLE 'table_name' ADD PRIMARY KEY pk_index('col');
- 唯一索引:用来建立索引的列的值必须是唯一的,允许空值
ALTER TABLE 'table_name' ADD UNIQUE index_name('col');
- 普通索引:用表中的普通列构建的索引,没有任何限制
ALTER TABLE 'table_name' ADD INDEX index_name('col');
- 全文索引:用大文本对象的列构建的索引
ALTER TABLE 'table_name' ADD FULLTEXT INDEX ft_index('col');
- 组合索引:用多个列组合构建的索引,这多个列中的值不允许有空值
ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3');
下面分别介绍下 5种索引的使用场景
- 主键索引应该是最常见的索引,我们在创建表的时候一般都会创建主键,并且打上主键索引。主键上会有非空性,唯一性。常规的主键还会有自增性。当我们在where 条件中指定主键为搜索条件时,速度就会非常的快
- 唯一索引一般用于数据本身可以保证唯一,并且有经常查询又不常修改的数据。比如常见的用户邮箱,用户手机号,身份证,银行卡等。唯一索引的。唯一索引的用处除了能提高查询效率以外。当表里插入或修改的数据在索引中已经出现过了,MYSQL就拒绝这一次修改或者插入。这样就可以避免数据出现重复
- 普通索引的使用场景其实就是数据不适合使用唯一索引或者全文索引。但是又经常会作为条件来查询或者排序,这个时候就会用到普通索引。常见的会有排序的字段sort 或者用户的姓名 name
- 全文索引对应的场景比较单一。就是那种大段内容存储,还需要模糊查询的。当我使用LIKE '%xxxx%'的时候是不走索引的。解决方案就是全文索引。不过需要注意的是模糊查询带有全文索引的字段就不能使用LIKE了。需要使用下面的语句来查询
SELECT * FROM table_name MATCH(ft_index) AGAINST('查询字符串');
- 组合索引我认为是根据业务来。比如一个查询语句经常执行。但是字段又不常修改。可以使用组合索引。组合索引比起对多个字段加上单独的索引来说,更节约磁盘的空间。因为本身建立索引就对性能有压力。建立一个组合索引三个字段,比分别建立三个字段的普通索引 开销要小。
在组合索引这里展开一下。
当我们使用了组合索引的时候,就需要遵循最左前缀原则
什么是最左前缀原则呢?就是在设置符合索引的时候尽量在被设置索引的字段查询范围和使用频次做一个排序。比如A字段 比B字段的查询范围和频次更高。就更应该把A字段排到左边。同理在编写查询语句的时候
也应该遵循这个逻辑。
这里假如 有联合索引 (a,b,c)三个字段
SELECT * FROM table_name WHERE a=1;//索引有效
SELECT * FROM table_name WHERE b='xx';//索引无效
SELECT * FROM table_name WHERE a=1 AND b='xx';//索引有效
SELECT * FROM table_name WHERE b='xx' AND a=1;//索引有效
SELECT * FROM table_name WHERE a=1 AND c='hahahaha';//索引有效
SELECT * FROM table_name WHERE b='xx' AND c='hahahaha';//索引无效
SELECT * FROM table_name WHERE a=1 AND b='xx' AND c='hahahaha';//索引有效
所以结合上面的例子
可以简单的理解为当创建(a,b,c)联合索引时,相当于创建了(a)单列索引,(a,b)联合索引以及 (a,b,c)联合索引
那么在编写sql的时候就应该往能使用索引的方式去靠
还有就是 在组合索引中字段不能有NULL值。如果有NULL怎么查索引的都是无效的
索引的使用也是要讲基本法的
什么场景不适合用索引?
- 数据过少的表,不需要用索引。因为数据较少,MYSQL会将数据读到内存里去,有点类似于缓存。这样查询速度会非常快。不要使用索引
- 经常增删改的字段不要使用索引。因为本身建立索引和维护索引是有开销的。如果经常变化的字段加上索引会拖慢操作的效率
- 不常被作为条件的字段,不要使用索引。不作为条件的字段除了无法通过索引加速以外,还占用磁盘空间。带来了维护压力
什么场景适合使用索引?
- 首先当然是主键索引。每个表都应该有主键索引
- 经常作为查询条件在WHERE或者ORDER BY 语句中出现的列要建立索引
- 查询中与其他表关联的字段,外键关系建立索引
- 业务上要防止重复的字段,应该加上唯一索引
- 用于聚合函数的字段,比如 count(col) sum(col)。应该建立索引
最后,很多朋友会问,我加了索引,但是不知道sql到底有没有用到索引。这个时候,只需要拿出索引大杀器explain
在你的sql前面就可以了
explain工具
概要描述:
- id:选择标识符
- select_type:表示查询的类型。
- table:输出结果集的表
- partitions:匹配的分区
- type:表示表的连接类型
- possible_keys:表示查询时,可能使用的索引
- key:表示实际使用的索引
- key_len:索引字段的长度
- ref:列与索引的比较
- rows:扫描出的行数(估算的行数)
- filtered:按表条件过滤的行百分比
- Extra:执行情况的描述和说明
结语:
其实关于索引的知识点还有很多很多,我也不是专业的DBA,只能说是在后端开发的角度去介绍下会经常用到的东西。还有就是数据库不同的引擎,也不完全一样。所以这篇文章算是抛砖引玉了,希望以前不太关注小伙伴能重视索引,也就可以了。
如果这篇文章对你有帮助的话,请点个赞。要是能加个关注就更好了。
网友评论