索引的概念

索引是特殊数据结构:  定义在查找时作为查找条件的字段

索引实现在存储引擎

功能:

1.约束数据

2.加速查询

优点:

索引可以降低服务需要扫描的数据量,减少了IO次数

索引可以帮助服务器避免排序和使用临时表

索引可以帮助将随机I/O转为顺序I/O

缺点:

占用额外空间,影响插入速度

索引的查询方式

b+tree索引

二叉树结构二分查找(按顺序存储)   在2的n次方的总记录数中,找到某条记录只需要n次查询即可

索引列的行数据最终都会在叶子页按顺序存储,节点页存储的是索引值的索引.非叶子节点只是为了方便算法寻找叶子节点

叶子节点比较特别,他们的指针指向的是被索引的数据,而不是其他的节点页(不同的引擎指针类型不同),其实在根节点与叶子节点之间可能有很多层节点页,树的深度和表的大小直接相关

btree树索引列是顺序组织存储的,所以很适合查找范围数据

创建索引   key(last_name,first_name,dob))

索引对多个值进行排序的依据是create table语句中定义索引时的列顺序

可以使用btree索引的查询类型,btree索引使用用于全键值、键值范围、或者键前缀查找,其中键前缀查找只适合用于根据最左前缀的查找。前面示例中创建的多列索引对如下类型的查询有效:

A:全值匹配

        全值匹配指的是和索引中的所有列进行匹配,即可用于查找姓名和出生日期

B:匹配最左前缀

      只查找姓,即只使用索引的第一列

C:匹配列前缀

       可以只匹配某一列值的开头部分,如:匹配以J开头的姓的人,这里也只是使用了索引的第一列,且是第一列的一部分

D:匹配范围值

如查找姓在allen和barrymore之间的人,这里也只使用了索引的第一列

E:精确匹配某一列并范围匹配另外一列

     如查找所有姓为allen,并且名字字母是K开头的,即,第一列last_name精确匹配,第二列first_name范围匹配

F:只访问索引的查询

btree通常可以支持只访问索引的查询,即查询只需要访问索引,而无需访问数据行,即,这个就是覆盖索引的概念。需要访问的数据直接从索引中取得。

索引排序

因为索引树中的节点是有序的,所以除了按值查找之外,索引还可以用于查询中的order by操作,一般来说,如果btree可以按照某种方式查找的值,那么也可以按照这种方式用于排序

所以,如果order by子句满足前面列出的几种查询类型,则这个索引也可以满足对应的排序需求

btree索引的使用限制 

A:如果不是按照索引的最左列开始查找的,则无法使用索引(注意,这里不是指的where条件的顺序,即where条件中,不管条件顺序,只要where中出现的列在多列索引中能够从最左开始连贯起来就能使用到多列索引)

B:不能跳过索引中的列,如:查询条件为姓和出生日期,跳过了名字列,这样,多列索引就只能使用到姓这一列

C:如果查询中有某个列的范围查询,则其右边所有列都无法使用索引优化查询,如:where last_name=xxx and first_name like ‘xxx%’ and dob=’xxx’;这样,first_name列可 以使用索引,这列之后的dob列无法使用索引。

hash索引

基于哈希表实现,只有精确匹配索引所有列的查询才有效,对于每一行数据,存储引擎都会对所有的索引列的值计算一个哈希码,哈希码是一个较小的值,并且不同键值的行计算出来的哈希码不一样,哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。

mysql> select * from testhash;

+-------+-----------+
| fname | lname     |
+-------+-----------+
| Arjen | Lentz     |
| Baron | Schwartz  |
| Peter | Zaitsev   |
| Vadim | Tkachenko |
+-------+-----------+
4 rows in set (0.00 sec)
 
假设索引使用假想的哈希函数f(),它返回下面的值:
f('Arjen')=2323
f('Baron')=7437
f('Peter')=8784
f('Vadim')=2458
 
则哈希索引的数据结构如下:
槽:        值:
2323        指向第1行的指针
2458        指向第4行的指针
7437        指向第2行的指针
8784        指向第3行的指针
哈希索引自身只需要存储对应的哈希值,所以索引的结构十分紧凑,这让哈希索引查找的速度非常快
 
哈希索引限制

A:哈希索引只包含哈希值和行指针,而不存储字段值,所以不能使用索引中的值来避免读取行(即不能使用哈希索引来做覆盖索引扫描),不过,访问内存中的行的速度很快  (因为memory引擎的数据都保存在内存里),所以大部分情况下这一点对性能的影响并不明显。

B:哈希索引数据并不是按照索引列的值顺序存储的,所以也就无法用于排序

C:哈希索引也不支持部分索引列匹配查找,因为哈希索引始终是使用索引的全部列值内容来计算哈希值的.如:数据列(a,b)上建立哈希索引,如果只查询数据列a,则无法使用该索引

D:哈希索引只支持等值比较查询,如:=,in(),<=>(注意,<>和<=>是不同的操作),不支持任何范围查询(必须给定具体的where条件值来计算hash值,所以不支持范围查询)

 

索引的种类

普通索引

加速查询速度

主键索引

加速查找 + 不能为空 + 不能重复

唯一索引

加速查找 + 不能重复

组合索引(多列组成一个索引)

组合索引的效率要高于索引合并

1.联合主键索引
   2.联合唯一索引
   3.联合普通索引

全文索引

给整个数据库创建索引表

覆盖索引

id是一个主键索引
    查询的数据直接从索引文件中就可以获取无需再次到表中读取数据
    select id from testdata where id=10000;

索引合并

name 是一个普通索引
    id 是一个主键索引
    在过滤条件的时候组合使用了多个单列索引
    select * from testdata where id=999 and name="aaa"

Mysql索引基础原理的更多相关文章

  1. MYSQL索引结构原理、性能分析与优化

    [转]MYSQL索引结构原理.性能分析与优化 第一部分:基础知识 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页 ...

  2. MySQL——索引实现原理

    在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,本文主要讨论MyISAM和InnoDB两个存储引擎的索引实现方式. MyISAM索引实现 MyISAM引擎使用B+Tr ...

  3. 【转】由浅入深探究mysql索引结构原理、性能分析与优化

    摘要: 第一部分:基础知识 第二部分:MYISAM和INNODB索引结构 1.简单介绍B-tree B+ tree树 2.MyisAM索引结构 3.Annode索引结构 4.MyisAM索引与Inno ...

  4. 重新学习MySQL数据库4:Mysql索引实现原理

    重新学习Mysql数据库4:Mysql索引实现原理 MySQL索引类型 (https://www.cnblogs.com/luyucheng/p/6289714.html) 一.简介 MySQL目前主 ...

  5. Mysql索引基础

    Mysql索引基础 基本概念: 索引是一种特殊的数据库结构,可以用来快速查询数据库表中的特定记录.索引是提高数据库性能的重要方式.索引创建在表上,是对数据库表中一列或多列的值进行排序的一种结构.可以提 ...

  6. MySQL索引的原理,B+树、聚集索引和二级索引

    MySQL索引的原理,B+树.聚集索引和二级索引的结构分析 一.索引类型 1.1 B树 1.2 B+树 1.3 哈希索引 1.4 聚集索引(clusterd index) 1.5 二级索引(secon ...

  7. 重新学习Mysql数据库4:Mysql索引实现原理和相关数据结构算法

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  8. MySQL索引结构原理分析

    我们在学习MySQL的时候经常会听到索引这个词,大概也知道这是什么,但是深究下去又说不出什么道道来.下面将会比较全面的介绍一下关于索引! 1 索引是什么? 这里用百度百科的一句话来说,在关系数据库中, ...

  9. MySQL——索引基础

    本篇文章,我们将从索引基础开始,介绍什么是索引以及索引的几种类型,然后学习如何创建索引以及索引设计的基本原则. 本篇文章中用于测试索引创建的user表的结构如下: 什么是索引 索引(在 MySQL 中 ...

随机推荐

  1. Linux设备驱动剖析之Input(一)

    前言 以前在移植Qt到开发板上时只知道在配置文件中需要指定触摸屏的设备文件/dev/input/event0,仅此而已.直到一年半前突然想到用红外遥控器控制Tiny6410开发板上的Android系统 ...

  2. Docker之OVS网络

    OVS介绍 什么是OpenVSwich? OpenvSwich:开放虚拟交换标准,是一种基于开源Apache2.0许可证的多层软件交换机,专门管理多租赁云计算网络环境,支持KVM.Xen等虚拟化技术. ...

  3. ASP.NET 前端Ajax获取数据并刷新

    控制器中↓ /// <summary> /// 根据ID来进行展示数据 /// </summary> /// <param name="instru_id&qu ...

  4. HDU 5992/nowcoder 207K - Finding Hotels - [KDTree]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5992 题目链接:https://www.nowcoder.com/acm/contest/207/K ...

  5. let 与 const 的用法

    let 与 const 的用法 let 用来声明变量,并且会在当前作用域形成 代码块 conts 用来声明常量,所谓常量就是物理指针不可以更改的变量. 所谓代码块,最简单的做法就是(这个 {} 就是一 ...

  6. 【绿书】 模拟,rep大坑

    https://vjudge.net/contest/229603#problem/B 绿书题 大模拟,绿书上用了个比较麻烦的输入,其实只要getchar()!='0'就行 坑: rep(i,0,s. ...

  7. python-----多线程、线程池、进程池

    import threadingimport time ###############################多线程################################------ ...

  8. 变长编码表 ASCII代码等长编码

    小结: 1.ASCII编码.GBK编码不是变长编码: 2.数据压缩: 示例: aabacdab → 00100110111010 → |0|0|10|0|110|111|0|10| → aabacda ...

  9. Chap7:民间用语[《区块链中文词典》维京&甲子]

  10. 安装多个java后,java版本不对

    参考资料: https://www.cnblogs.com/Kidezyq/p/5781131.html 主要原因是javac -version是由JAVA_HOME指定的路径中的java版本来决定的 ...