在了解了索引的基础知识及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+树索引的“最左前缀”原则。

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

第一原则是,如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。

第二原则是,空间。当两个字段存在一个明显比另一个大时,例如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范围查询如何建索引_MySQL索引(二):建索引的原则相关推荐

  1. mysql 建索引_mysql数据库正确建立索引及使用

    普通mysql运行,数据量和访问量不大的话,是足够快的,但是当数据量和访问量剧增的时候,那么就会明显发现MySQL很慢,甚至down掉,那么就要考虑优化我们的mysql了.其中优化mysql的一个重要 ...

  2. mysql教程联合索引_MySQL中的联合索引学习教程

    联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c). 可以支持a | a,b| ...

  3. mysql源码自适应哈希索引_MySQL 自适应哈希索引

    一.介绍 哈希(hash)是一种非常快的查找方法,一般情况下查找的时间复杂度为O(1).常用于连接(join)操作,如Oracle中的哈希连接(hash join). InnoDB存储引擎会监控对表上 ...

  4. mysql 创建列的索引_mysql创建多列索引及优化

    原文连接地址:http://leeyin.iteye.com/blog/441350 什么是索引? 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查 ...

  5. mysql原生建立索引_MySQL学习笔记之索引

    索引是存储引擎用于快速找到记录的一种数据结构. 索引对于良好的性能非常关键.尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要.在数据量较小且负载较低时,不恰当的索引对性能的影响可能还不明显,但 ...

  6. MySQL支持的四种索引_Mysql常见四种索引的使用

    提到mysql优化,索引优化是必不可少的.其中一种优化方式 --索引优化,添加合适的索引能够让项目的并发能力和抗压能力得到明显的提升. 我们知道项目性能的瓶颈主要是在"查(select)&q ...

  7. mysql优化varchar索引_MySQL优化--概述以及索引优化分析

    一.MySQL概述 1.1.MySQL文件含义 通过如下命令查看 show variables like '%dir%'; MySQL文件位置及含义 名称 值 备注 basedir /usr/ 安装路 ...

  8. mysql二级索引_mysql 什么是二级索引

    ALTER TABLE t1 ADD INDEX(or CREATE INDEX) ALTER TABLE t1 ADD FULLTEXT INDEX ALTER TABLE t1 ADD COLUM ...

  9. mysql如何给text字段添加索引_MySQL 是如何利用索引的

    阅读本文大概需要 4 分钟. 一.前言 在 MySQL 中进行 SQL 优化的时候,经常会在一些情况下,对 MySQL 能否利用索引有一些迷惑.例如: MySQL 在遇到范围查询条件的时候就停止匹配了 ...

  10. mysql 不执行索引_mysql使用不上索引的几种情况

    索引出现的主要目的是提高查询语句的执行效率.为了能够提高查询语句的性能,我们基本的做法都是在查询条件字段上合理地增加索引来实现的. 不过,你是否碰到过类似的情况,查询的条件字段明明有创建索引,可是My ...

最新文章

  1. c语言逆序输出字符串指针,菜鸟求助-如何用指针法将一串字符按单词的倒序输出?如:i love yo...
  2. Spring 注解 @Resource和@Autowired(转)
  3. 012-简单辅助元素
  4. 3DSlicer18:Layouts
  5. BZOJ 2759 一个动态树好题 (LCT)
  6. Ubuntu连接WiFi
  7. Ubuntu中vi / vim编辑器快捷操作
  8. VC++ 添加用户环境变量
  9. 用什么软件测试电视分辨率,4k电视分辨率测试图
  10. DataGrip连接不上本地localhost数据库解决办法
  11. cad插入块_CAD制图软件中如何快速绘制推拉窗平面简图
  12. C#创建文件,覆盖文件,读取文件
  13. 意间ai绘画怎么输入关键词,让图片变得好看?
  14. CubieBoard2串口
  15. cocos creator切换场景闪退_#Cocos Creator# 为什么音乐音效在场景切换的时候自动停止了?...
  16. Python 利用免费HTTP代理IP网站多线程筛选出自己的代理IP池
  17. Linux中的0.0.0.0和 ::
  18. python:计划持有基金n年,求n年的每年复利_利率
  19. 分享一款好用的微信相册小程序《群相册大师》
  20. php 邮箱附件 大小限制,不能作为电子邮件的附件发送的是什么?

热门文章

  1. jupyter 或者 zeppelin 的下一代工具 polynote
  2. SSLOJ 1459.空间简单度【扫描线】【线段树】
  3. ElasticSearch 2 (25) - 语言处理系列之同义词
  4. matplotlib作图系列之内置颜色使用(一)
  5. 用CSS画小猪佩奇,你就是下一个社会人! js将“I am a coder”反转成 “coder a am I”,不许用split,join,subString,reverse;求解方法三...
  6. 青海行--(7月28日)凯旋归程
  7. C#上位机(数据校验发送指令来控制下位机)
  8. 数控技术转行java_我29岁想转行数控却找不到工作
  9. GPRS模块功能简介(I)SGSN功能
  10. 【java】数组的定义以及初级运用精讲(起点闭关计划)