MySQL索引

 

MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。

可以类比字典,如果要查“mysql”这个单词,我们肯定需要定位到m字母,然后从下往下找到y字母,再找到剩下的sql。如果没有索引,那么你可能需要把所有单词看一遍才能找到你想要的,如果我想找到m开头的单词呢?或者ze开头的单词呢?是不是觉得如果没有索引,这个事情根本无法完成?

索引类型
MySQL目前主要有以下几种索引类型:

1.普通索引

2.唯一索引

3.主键索引

4.组合索引

5.全文索引

索引创建

普通索引

这是最基本的索引,它没有任何限制。创建方式:

CREATE INDEX indexName ON table_name (column_name)

  

唯一索引
它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。创建方式:

CREATE UNIQUE INDEX indexName ON table_name (username(length))

  

主键索引

是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引:

CREATE TABLE `table_name` (`id` int(11) NOT NULL AUTO_INCREMENT ,`title` char(255) NOT NULL ,PRIMARY KEY (`id`));

  

组合索引
指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合:

ALTER TABLE `table_name` ADD INDEX name_city_age (name,city,age);

 

全文索引
全文索引(也称全文检索)是目前搜索引擎使用的一种关键技术。它能够利用【分词技术】等多种算法智能分析出文本文字中关键词的频率和重要性,然后按照一定的算法规则智能地筛选出我们想要的搜索结果。
创建方式:

CREATE FULLTEXT INDEX index_content ON table_name(content)

  

索引的数据结构

首先,数据库索引使用树来存储,因为树的查询效率高,而且二叉查找树还可以保持数据的有序。
那么索引为什么没有使用二叉树来实现呢?
其实从算法逻辑上讲,二叉查找树的查找速度和比较次数都是最小的,但是从Mysql的角度讲,我们不得不考虑一个现实问题:磁盘IO。
当我们利用索引查询的时候,不可能把整个索引全部加载到内存,只能逐一加载每个磁盘页,磁盘页对应索引树的节点。
那么Mysql衡量查询效率的标准就是磁盘IO次数。

如果我们利用二叉树作为索引结构,那么磁盘的IO次数和索引树的高度是相关的。
那么为了提高查询效率,就需要减少磁盘IO数。为了减少磁盘IO的次数,就需要尽量降低树的高度,需要把原来“瘦高”的树结构变的“矮胖”,树的每层的分叉越多越好,因此b+树正好符合我们的要求。

b+树

b+ 树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。

我们先来看看b+树存储结构,比如有一张用户表(user),数据如下:

id  其他字段
3  
5  
9  
10  
13  
15  
28  
29  
36  
60  
75  
79  
91  
95  

相应b+树,如下图:

​​
如上图,这就是一个b+树。其中浅蓝色的块我们称之为一个磁盘块,可以看到每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示),如磁盘块1包含数据项17和35,包含指针P1、P2、P3,P1表示小于17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块。真实的数据存在于叶子节点即3、5、9、10、13、15、28、29、36、60、75、79、91、95。非叶子节点只不存储真实的数据,只存储指引搜索方向的数据项,如17、35并不真实存在于数据表中。

b+树的查找过程

 比如,查询id为29的记录:

select * from  where  id=29

  

如上图所示,如果要查找数据项29,那么首先会把磁盘块1由磁盘加载到内存,此时发生一次IO,在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针,内存时间因为非常短(相比磁盘的IO)可以忽略不计,通过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次IO,29在26和30之间,锁定磁盘块3的P2指针,通过指针加载磁盘块8到内存,发生第三次IO,同时内存中做二分查找找到29,结束查询,总计三次IO。
真实的情况是,3层的b+树可以表示上百万的数据,如果上百万的数据查找只需要三次IO,性能提高将是巨大的,如果没有索引,每个数据项都要发生一次IO,那么总共需要百万次的IO,显然成本非常非常高。

缺点


上面说明都是索引的优点,索引同样的也存在缺点:
1.虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行insert、update和delete。因为更新表时,不仅要保存数据,还要保存一下索引文件。
2.建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会增长很快。
3.索引只是提高效率的一个因素,如果有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。

最后


MySQL改善查询性能改善的最好方式,只有我们明白索引的原理,才能更合理地使用索引!

文章首发于公众号【编程乐趣】,欢迎大家关注。

细说MySql索引原理的更多相关文章

  1. Mysql高手系列 - 第22篇:深入理解mysql索引原理,连载中

    Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 欢迎大家加我微信itsoku一起交流java.算法.数据库相关技术. 这是Mysql系列第22篇. 背景 使用mys ...

  2. MySQL索引原理及慢查询优化

    原文:http://tech.meituan.com/mysql-index.html 一个慢查询引发的思考 select count(*) from task where status=2 and ...

  3. (转)MySQL索引原理及慢查询优化

    转自美团技术博客,原文地址:http://tech.meituan.com/mysql-index.html 建索引的一些原则: 1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到 ...

  4. MySQL索引原理及慢查询优化 转载

    原文地址: http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能 ...

  5. MySQL索引原理及慢查询优化(转)

    add by zhj:这是美团点评技术团队的一篇文章,讲的挺不错的. 原文:http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰 ...

  6. 【转载】MySQL索引原理及慢查询优化

    原文链接:美团点评技术团队:http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型 ...

  7. MySQL索引原理与慢查询优化

    索引目的 索引的目的在于提高查询效率,可以类比字典,如果要查“mysql”这个单词,我们肯定需要定位到m字母,然后从下往下找到y字母,再找到剩下的sql.如果没有索引,那么你可能需要把所有单词看一遍才 ...

  8. 干货:MySQL 索引原理及慢查询优化

    MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓"好马配好鞍",如何能够更好的使用它,已经成为开发工程师的必修 ...

  9. MySQL索引原理及慢查询优化(转自:美团tech)

    背景 MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓“好马配好鞍”,如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会 ...

  10. 知识点:Mysql 索引原理完全手册(2)

    知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) 八. 联合索引与覆盖索引 ...

随机推荐

  1. 最短路之Dijkstra

    Dijkstra算法: Dijkstra是一种求解 非负权图 上单源最短路径的算法. 思路:将所有结点分为两个集合:已经确定最短路径的点(S)和未确定最短路长度的点集(T),开始时所有点都属于T 初始 ...

  2. 代码随想录Day19

    235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个 ...

  3. 004.MinIO-DirectPV分布式存储部署

    MinIO部署介绍 部署概述 Kubernetes hostpath.local和本地静态配置都存在需要事先在node节点准备好可用的块存储或文件系统,例如对插入的硬盘,或者磁盘阵列做分区格式化,文件 ...

  4. 玄机蓝队靶场_应急响应_02:apache日志分析

    日志分析这块,感觉都是对grep.awk.sort.wc.uniq,这几个命令的使用. 一:靶场 (1)直接cd到linux日志, cd /var/log 发现apache2目录, cd ./apac ...

  5. Typora 上传到 Github 实现笔记同步管理

    首先在 Github 上 new 一个 repository ,我建的名称是 md_notes 然后在本地 terminal 中启动以下命令新建一个 ssh key  ssh-keygen -o 生成 ...

  6. 什么是电商API

    ​ 是电子商务平台提供给开发者和商家的一种技术接口,它允许第三方应用程序访问和操作平台的数据和服务.电商API的使用可以极大地提高业务效率,促进创新,并且为商家提供更多的商业机会. 以下是电商API的 ...

  7. Docker高级:Redis集群实战!4主4从缩容到3主3从,怎么处理?

    在上一篇,我们学会了redis集群的扩容.从3主3从扩容到4主4从. 那么,接着,活动过去了.流量没有那么大了.需要缩容了.从4主4从缩容到3主3从了.那么这个时候又该怎么处理呢? PS本系列:< ...

  8. Go 必知必会:探索 Go 语言中的数组和切片深入理解顺序集合

    文末有面经共享群 在 Go 语言的丰富数据类型中,数组和切片是处理有序数据集合的强大工具,它们允许开发者以连续的内存块来存储和管理相同类型的多个元素.无论是在处理大量数据时的性能优化,还是在实现算法时 ...

  9. MS SQL的ROUND函数用来数值的四舍五入

    MS SQL的ROUND函数用来数值的四舍五入 MS SQL要进行数值的四舍五入,有一好用的函数ROUND. 语法 ROUND ( numeric_expression , length [ ,fun ...

  10. numpy argsort排序如何让其稳定排序

    numpy.argsort(a, axis=-1, kind=None, order=None) Parameters: aarray_like Array to sort. axis int or ...