索引原理
如果一本新华字典假如没有目录,想要查找某个字,就不得不从第一页开始查找,一直找到最后一页(如果要找的字在最后一页),这个过程非常耗时,这种场景相当于数据库中的全表扫描的概念,也就是循环表中的每一条记录看看该记录是否满足条件,扫描次数为表的总记录数。
新华字典中都会有目录都有查找方法(比如按拼音查找、按部首查找),假如按拼音查找,我们根据拼音就能瞬速定位到要找的汉字,而这个汉字后面还有这个汉字对应的页数,我们直接翻到该页就能找到,整个查找过程非常快,用时非常短。这个原理就是数据库中索引的原理。这里的按拼音查找、按部首查找是两种不同的查找方式,通过每种方式都能快速找到,在数据库中也有很多查找方式,称之为索引方法,有BTREE、HASH两种方式
BTREE:一颗倒立的树,每个节点都有父节点,父节点下面的节点称之为子节点(叶子节点),比父节点值小的位于父节点下面的左方,比父节点值大的子节点放置在父节点下面的右下方。
记录索引列的值和对应的记录所在的磁盘位置,每次排除掉一半, 检索一次相当排除掉2的n次幂,使用二叉树排除30次相当于全表排除10亿次。比如查询id=11的值,首先和6比,比6大就排除掉左边的,继续和9比较,11比9大,又排除掉左边的一般,和11进行比较,相等就找到了结果。当数据量很大的时候,每次都排除掉一半,排除的数据量是非常惊人的。
Hash:Hash索引只能等值匹配,想范围查询,左前缀查询都不适用, 其余大部分场景
为什么要使用索引?
索引类型
关于唯一性有两种做法:
全文索引只能用于MyISAM引擎,通常如果用到全文索引一般通过Elasticsearch、Solr、Lucene等技术来实现。
索引语法
-- 创建普通索引:
create index 索引名 on 表(列1【ASC|DESC】, 列2 ASC|DESC】)
-- 创建唯一索引
create unique index on 表名(列名)
③索引字段
一个索引可以针对一个字段进行创建,也可以指定多个字段创建复合索引。
④在哪些列上适合添加索引
ASC | DESC 选项 除非显式指定降序 (DESC),否则列以升序 (ASC) 排序。不管索引是升序排列还是降序排列,在执行升序或降序 ORDER BY 操作时都会使用索引。但是如果通过混合的升序和降序属性来执行 ORDER BY,则仅当索引是用同样的升序和降序属性创建的时才使用索引。
-- 可以显式指定索引字段的顺序,默认为升续
CREATE INDEX idx_username ON tbl_user(username ASC);
-- 对于较长的字符内容可以指定前N个字节创建索引,没必要为整个值都创建索引
CREATE INDEX idx_username ON tbl_user(contnet(20) ASC);
-- 复合索引:基于多个字段共同创建索引(区分度最大的字段放在前面,经常会被使用到的列在前面)
CREATE INDEX idx_username_email ON tbl_user(username, email);
-- 删除索引
DROP INDEX idx_username ON tbl_user;
-- 查看某个表的索引,两种方式效果一样
SHOW INDEX FROM tbl_user;
SHOW KEYS FROM tbl_user;
show index from 表名;
show keys from 表名;
一般是先删除再创建
- 删除重复和冗余的索引(第三方工具需要额外安装)
pt-duplicate-key-checker h=127.0.0.1
-- 更新索引统计信息及减少索引碎片
ANALYZE TABLE <table_name>
-- 清理碎片(注意会锁表)
OPTIMIZE table <table_name>