索引使用的基本原则

  咱们在建表的时候最好建立自增主键,这样非主键索引占用的空间就比较小。这种方式插入数据都是追加数据,不涉及到数据页分裂。但也不是全部场景下都须要自增主键,好比有些业务场景的需求是只有一个索引而且该索引必须是惟一索引,因为没有其余索引,就不用考虑辅助索引的存储空间消耗,能够直接将这个索引设为主键。sql

覆盖索引数据库

  好比ID、k是表T中的主键索引和辅助索引,如今有一条查询需求:性能优化

select ID from T where k between 3 and 5;

  由于k索引树中叶子结点值存放的就是ID值,能够直接查询到结果,这时就不须要再回表。若是查询的结果是联合索引的字段,一样不须要回表操做。索引k覆盖了咱们的查询需求,这种索引就叫覆盖索引。因为覆盖索引能够减小搜索索引树的次数,所以这是一个经常使用的数据库性能优化方法。 性能

联合索引优化

  简要的说就是由多个字段组成的索引,假设如今有张市民信息表T:spa

CREATE TABLE `tuser` (
  `id` int(11) NOT NULL,
  `id_card` varchar(32) DEFAULT NULL,
  `name` varchar(32) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `ismale` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `id_card` (`id_card`),
  KEY `name_age` (`name`,`age`)
) ENGINE=I

  里面有身份证号 id_card、姓名 name等字段,有个高频请求:根据身份证号查询姓名,那么咱们就能够建立 (id_card, name) 联合索引,这里会用到覆盖索引,再也不须要回表查询整行记录。索引的维护是有代价的,怎样创建联合索引须要考虑具体的业务场景。code

最左前缀原则blog

  有时候咱们会遇到不常见的查询请求,好比根据身份证号查询市民的家庭住址。若是咱们走全表扫描效率过低,单首创建一个索引又浪费空间,这会就能够用B+树索引的最左前缀原则。用联合索引 (name, age) 来讲明这个概念:索引

        

  好比需求是查询全部名字是张三的人,能够快速定位到 ID4,而后向后扫描全部知足条件的数据。若是查询姓张的人,sql里条件部分能够这样写 “ where name like '张%' ”,一样也能用到上面的联合索引。这里最左前缀能够是联合索引的最左N个字段,也能够是字符串索引的最左M个字符。资源

  那咱们该如何创建联合索引呢?首先要遵循一个原则:若是经过调整索引顺序,能够少维护一个索引,那么这个顺序就是优先考虑的。好比上面的(id_card,name)索引,根据 id_card 查询家庭住址就不要再创建 联合索引了。

若是既有联合查询,又有基于a、b各自的查询,好比查询语句中只有索引b是不能用联合索引 (a,b)的。那么就要创建两个索引,考虑的原则是索引占用空间。好比市民信息表中 name 字段比 age 占用空间大,就建立一个 (name, age)联合索引和一个 (age)的单字段索引。

  对于联合索引,还有一个问题:字段中不符合最左前缀的部分会怎么样?一样用上面的 (name, age) 索引来讲明,如今有一个需求:“查询出名字第一个字是张,年龄为10岁的男孩”。sql是这样的:

select * from T where name like '张%' and age = 10 and ismale = 1;

在MySQL5.6以前,只能不停的回表查到最后的结果;5.6以后引入了索引下推优化,就是在索引遍历过程当中,对索引中包含的字段中先作判断,过滤掉不知足条件的记录,减小回表的次数。用两个图来解释:分别是优化先后

能够看到原来是4次回表,优化后变成2次,减小了对资源的访问。

相关文章
相关标签/搜索