汇集索引(InnoDB,使用B+Tree做为索引结构)mysql
在一个结构中保存了b-tree索引和数据行;按照主键的顺序存储在叶子页上;算法
主键索引:叶节点存储key-value为(主键数据:全部剩余列数据)sql
二级索引(非聚簇索引):叶节点存储key-value为(索引列数据:主键数据)服务器
非叶节点只存储 索引列ide
优势:函数
能够把相关数据保存在一块儿,如根据用户id汇集电子邮箱信息,只须要读取少数的数据页就能获取某个id用户的所有邮件;性能
数据访问更快,将索引和数据保存在同一个b-tree中;优化
使用覆盖索引扫描的查询能够直接使用叶节点中的主键值;spa
缺点:代理
插入速度严重依赖于插入顺序,按照主键的顺序插入是加载数据到innodb表中速度最快的方式;
插入新行可能面临页分裂的问题,页分裂致使表占用更多磁盘空间;
经过二级索引须要两次查找,存储引擎找到二级索引的叶子节点得到对应的主键值,根据这个值去聚簇索引中找到对应的行
主键:
若是表没有什么数据须要被汇集(如上述邮件用户id),那么能够定义一个代理键做为主键,使用auto_increment自增列;
非汇集索引(MyISAM使用B+Tree做为索引结构)
按照数据插入顺序存储在磁盘上,访问数据须要一次系统调用;
主键索引/二级索引:叶节点存储(索引列数据:数据在磁盘上的行号)
对比:
InnoDB提供事务支持事务,外键等功能;MyISAM不支持。
InnoDB支持行级锁;MyISAM只支持表级锁
InnoDB要求必须有主键;MyISAM容许没有任何索引和主键的表存在,索引都是保存行的地址。
覆盖索引
一个索引包含(或者说覆盖)全部须要查询的字段的值
覆盖索引要存储索引列的值,只能用b-tree索引作覆盖索引(不能用哈希索引,全文索引等)
优势
1. MyISAM存储引擎在内存中只存储索引,覆盖索引不须要进行系统调用;
2. innodb存储引擎的聚簇索引机制,二级主键若是能覆盖查询,能够避免对主键索引的二次查询;
全文索引
但愿经过关键字的匹配来进行查询过滤,而不是经过常规的数值比较,范围过滤操做;
MyISAM的全文索引是一类特殊的B-Tree索引,共有两层,第一层是全部关键字,对于每个关键字的第二层,包含的是一组相关的“文档指针”;
对于文档对象中的全部词语的过滤条件:
1. 停用词列表中的词语都不会被索引
2. 长度大于指定范围和小于指定范围的词语不会被索引
另外,全文索引不会存储关键字具体匹配在哪一列。
1. 天然语言全文索引
根据where子句中的MATCH AGAINST区分是否使用全文索引
Eg.在表file_text的字段title,description上创建fulltext全文索引
Select film_id,title,right(description,25)
Match(title,description) against(‘factory casualties’) as relevance
From file_text where Match(title,description) against(‘factory casualties’);
结果:
Film_id title right(description,25) relevance
831 spirited casualties a car is a baloon factory 8.4692449702
126 casualties encino face a boy in a monastery 5.2615661621
... ...
函数match()将返回关键词的匹配相关度,是一个浮点数。
2. 布尔全文索引
用户能够自定义被搜索词语的相关性;用户能够经过一些前置修饰符定制搜索:
example meaning
Dinosaur 包含dinosaur的行rank值更高
-dinosaur 包含dinosaur的行rank值更低
+dinosaur 行记录必须包含dinosaur
-dinosaur 行记录不能包含dinosaur
Dino* 包含以dino开头的单词的行rank值更高
Eg. Select film_id,title,right(description,25)
From file_text where Match(title,description) against(‘+factory +casualties’ in boolean mood);
结果:
Film_id title right(description,25)
831 spirited casualties a car is a baloon factory
搜索的关键词是不常见的词语时,比LIKE操做要快得多,由于是直接从索引中过滤记录。
全文索引的限制:
1. mysql的全文索引只有一种判断相关性的方法:词频。没有其余相关性排序算法,如存储的位置。
2. 只有全文索引所有在内存中时,性能才能很是好
3. 其余的where条件,只能在mysql完成全文搜索返回记录后才能进行
4. 全文索引不能存储列的实际值,不能用做覆盖扫描
5. 除了相关性排序,不能用做其余排序
配置和优化
1. 停用词表
2. 容许最小词长
在搜索的精度和搜索的效率之间找到合适的平衡点。
索引和锁
索引可让查询锁定更少的行,innodb只有在访问行时才会对其加锁,而索引能够减小innodb访问的行数,从而减小锁的数量;
可是,只有当innodb在存储引擎层可以过滤掉不须要的行时才有效,若是没法过滤,那么在innodb检索到数据并返回给服务器层,mysql才能应用where语句进行过滤,而innodb已经锁住了这些行,直到服务器层过滤完成后释放锁;
如:select actor_id from sakila.actor where actor_id < 5 (范围)and actor_id <> 1 (过滤) for update;
执行explain命令,显示type为range,表示mysql为该查询选择的执行计划是索引范围查询,即在存储引擎层只执行了actor_id < 5的条件,查询结果:2,3,4;而被锁定的数据行:1,2,3,4;
即便使用索引,也可能锁住一些不须要的行,可是不使用索引查找的话mysql会全表扫描并锁住全部的行。