在了解了索引的基础知识及B+树索引的原理后(如需复习请点这里),这一节我们了解一下有哪些建索引的原则,来指导我们去建索引。

建索引的原则

1. 联合索引

我们可能听一些数据库方面的专业人士说过:“把 Where 条件里面的列都建上索引”,从而给每个列给每个列建独立的索引,这个理解是非常错误的。

如果 Where 条件里有多种组合的查询条件,可以尝试建联合索引来减少索引数量,同时提升查询性能。

2. 覆盖索引

普通索引查到主键后,回到主键索引搜索的过程,称为回表。

当使用普通索引查询时,普通索引有我们所需结果的所有信息(字段),就可以直接提供查询结果,而不需要回表。也就是说,在这个查询里,索引已经被“覆盖了”查询需求,称为覆盖索引。

mysql> create table T (
ID int primary key,
k int NOT NULL DEFAULT 0,
s varchar(16) NOT NULL DEFAULT '',
index k(k))
engine=InnoDB; select ID from T where k between 3 and 5

上面的例子中,k索引树上已经包括了ID的值,就不需要回表了。

由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。

在使用覆盖索引时,要注意如果需要返回的字段较多,就要权衡空间和时间。因为覆盖索引要覆盖较多字段就需要更多的空间。

3. 最左前缀原则

假设我们有2个字段,例如身份证号和地址,现在有三种查询需求:按身份证号查询、按地址查询,以及按身份证号和地址查询。

如果每种需要都要创建一个索引,就显得有利浪费。

从上一篇文章里,我们了解到B+树的特点是有序的,因此我们可以只创建两个索引即满足上面的三种需求,分别是(身份证号,地址)和(地址)。这就是B+树索引的“最左前缀”原则。

在建立联合索引的时候,如何安排索引内的字段顺序:

  1. 第一原则是,如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。
  2. 第二原则是,空间。当两个字段存在一个明显比另一个大时,例如name和age,明显name要比age要大,此时应该建一个(name,age)的联合索引和一个(age)的单字段索引。

4. 前缀索引和索引选择性

有时候需要索引很长的字符列,这会让索引变得大且慢。一种策略是模拟哈希索引。

通常可以索引开始的部分字符,这样可以大大节约索引空间,从而提高索引效率。但这样也会降低索引的选择性。

索引的选择性指,不重复的索引值(也称为基数,cardinality)和数据表的记录总数(T)的比值,范围从1/T到1之间。

如何确定前缀索引的长度及创建前缀索引

假设有个订单表,其中有包括城市名称的字段(city,且城市名称为英文),下面来介绍一下如何确定前缀索引的长度。

mysql> create table orders (
ID int primary key,
city varchar(16) NOT NULL
)engine=InnoDB;

一种方法是计算完整列的选择性,并使前缀的选择性接近于完整列的选择性。

计算完整列的选择性:

mysql> SELECT COUNT(DISTINCT city)/COUNT(*) FROM orders;

在同一个查询中计算不同前缀长度的选择性:

mysql> SELECT COUNT(DISTINCT LEFT(city, 3))/COUNT(*) AS sel3,
COUNT(DISTINCT LEFT(city, 4))/COUNT(*) AS sel4,
COUNT(DISTINCT LEFT(city, 5))/COUNT(*) AS sel5,
COUNT(DISTINCT LEFT(city, 6))/COUNT(*) AS sel6,
COUNT(DISTINCT LEFT(city, 7))/COUNT(*) AS sel7
FROM orders;

创建前缀索引的方法:

mysql> ALTER TABLE orders ADD KEY (city(7));

5. 选择合适的索引顺序

在联合索引中,索引列的顺序是按照从左到右逐列进行排序的。因此索引可以按照升序或降序进行扫描,以满足精确符合列顺序的 ORDERY BY、GROUP BY 和 DISTINCT 等子句的查询需求。

因此联合索引的列顺序很重要。

如何选择索引的列顺序有一个经验法则:将选择性最高的列放到索引最前列。

这个经验法则在某些场景下有用,但可能在另外场景下,可能就没效了,这要根据具体情况进行分析。

参考资料

MySQL索引(二):建索引的原则的更多相关文章

  1. MySql(二)索引的设计与使用

    MySql(二)索引的设计与使用 一.索引概述 二.设计索引的原则 三.BTREE索引与HASH索引 一.索引概述 所有Mysql列类型都可以被索引,对相关列使用索引时提高select操作性能的最佳途 ...

  2. MySQL(二)索引背后的数据结构及算法原理

    本文转载自CodingLabs,原文链接 MySQL索引背后的数据结构及算法原理 目录 摘要 一.数据结构及算法基础 1. 索引的本质 2. B-Tree和B+Tree 3. 为什么使用B-Tree( ...

  3. SQL SERVER大话存储结构(4)_复合索引与包含索引

              索引这块从存储结构来分,有2大类,聚集索引和非聚集索引,而非聚集索引在堆表或者在聚集索引表都会对其 键值有所影响,这块可以详细查看本系列第二篇文章:SQL SERVER大话存储结构 ...

  4. 好文 | MySQL 索引B+树原理,以及建索引的几大原则

    Java技术栈 www.javastack.cn 优秀的Java技术公众号 来源:小宝鸽 blog.csdn.net/u013142781/article/details/51706790 MySQL ...

  5. MySQL数据库中的索引(二)——索引的使用,最左前缀原则

    上文中,我们了解了MySQL不同引擎下索引的实现原理,在本文我们将继续探讨一下索引的使用以及优化. 创建索引可以大大提高系统的性能. 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性. ...

  6. mysql索引二

    理解MySQL——索引与优化 写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优 的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储1 ...

  7. mysql(二)--mysql索引剖析

    1.1. 索引是什么 1.1.1.索引图解 维基百科对数据库索引的定义: 数据库索引,是数据库管理系统(DBMS)中一个排序的数据结构,以协助快速查询.更新数据库表中数据. 怎么理解这个定义呢?  首 ...

  8. 点评阿里JAVA手册之MySQL数据库 (建表规约、索引规约、SQL语句、ORM映射)

    下载原版阿里JAVA开发手册  [阿里巴巴Java开发手册v1.2.0] 本文主要是对照阿里开发手册,注释自己在工作中运用情况. 本文内容:MySQL数据库 (建表规约.索引规约.SQL语句.ORM映 ...

  9. Mysql索引分析:适合建索引?不适合建索引?【转】

    数据库建立索引常用的规则如下: 1.表的主键.外键必须有索引: 2.数据量超过300的表应该有索引: 3.经常与其他表进行连接的表,在连接字段上应该建立索引: 4.经常出现在Where子句中的字段,特 ...

随机推荐

  1. 直播软件开发关于Android、iOS中的视频采集步骤

    很多人对直播软件开发还是抱有想法的,但是在这个资本冷静的市场下,直播平台该怎么玩,在直播软件开发过程中哪些功能是必须具备的,这都是值得关注的话题.今天我们给大家分享一份详细的直播软件开发关于Andro ...

  2. ubuntu12.04管理文件系统工具

    ubuntu12.04管理文件系统工具 以前可以自动管理系统盘和移动硬盘,刚重新安装了UBUNTU12.04LTS之后不行了,原来是这个工具: "PCMANFM" 群星_-_偏偏喜 ...

  3. TCP Persist 坚持定时器

    1.坚持定时器在接收方通告接收窗口为0,阻止发送端继续发送数据时设定. 由于连接接收端的发送窗口通告不可靠(只有数据才会确认),如果一个确认丢失了,双方就有可能因为等待对方而使连接终止: 接收放等待接 ...

  4. 从头学起Verilog(三):Verilog逻辑设计

    引言 经过了组合逻辑和时序逻辑的复习,终于到了Verilog部分.这里主要介绍Verilog一些基础内容,包括结构化模型.TestBench编写和仿真.真值表模型. 这部分内容不多,也都十分基础,大家 ...

  5. JsonPath在接口自动化中的应用

    我理解jsonpath于json而言,就像是xpath在XML中的作用.用来确定json中某部分数据的语言.我更喜欢叫jsonpath表达式,因为这样好像是数学问题. 以前和小伙伴一起写接口自动化的时 ...

  6. 重要 | Spark分区并行度决定机制

    最近经常有小伙伴在本公众号留言,核心问题都比较类似,就是虽然接触Spark有一段时间了,但是搞不明白一个问题,为什么我从HDFS上加载不同的文件时,打印的分区数不一样,并且好像spark.defaul ...

  7. 关于vm.min_free_kbytes的合理设置推测

    前言 之前系统出现过几次hung住的情况,没有oom,也没有其它内存相关的信息,而linux设计就是去尽量吃满内存,然后再回收清理的机制 探讨 目前这个参数还没有找到合适的处理这个预留的参数,一般也没 ...

  8. 3-colorability

    目录 1.1 3-colorability 1.1.1 3元可满足规约到3着色 1.1.2 证明充分和必要性 1.1 3-colorability 一个图的三着色问题:要使得边两头的结点颜色互不相同. ...

  9. CSS 常用列表样式

    CSS 常用列表样式 CSS没学扎实,复习记录一下.下面是一些常用的属性 list-style-image 指定一个图片作为列表项的标记 默认值none,可设置为图片的url list-style-i ...

  10. 掌握这些springboot的配置方式,让你工作效率翻个倍!

    springboot的多种配置方式 java配置主要靠java类和一些注解,比较常用的注解有: @Configuration :声明一个类作为配置类,代替xml文件 @Bean :声明在方法上,将方法 ...