索引概述:

索引(也就是mysql中常说的键值key)是存储引擎用户快速找到记录的一种数据结构,这是索引的基本功能,索引对于良好的性能非常关键,尤其是当表中数据量

越来越大的时候,索引对性能的影响就越重要,在数据量较小且负载较低时,不恰当的索引对性能的影响可能不明显,但当数据量逐渐增大的时候,性能就会急剧下降.

理解索引最简单的方法:就是去看看一本书的"索引"部分,如果想在一本书中找到某个特定主题,一般会先看书的“索引”,根据“索引”找到对应的页码.在mysql中,存储

引擎用类似的方法使用索引,先在索引中找到对应值,然后根据匹配的索引记录找到对应的值,然后根据匹配的索引记录找到对应的数据行.

索引的类型:

一.B-Tree索引

在mysql中,索引是在存储引擎层而不是服务器层实现的,所以并没有统一的索引标准;不同存储引擎的索引的工作方式并不一样,也不是所有的存储引擎都支持所

有类型的索引,即使多个存储引擎支持同一种类型的索引,其底层的实现也可能不同.

如果没有特别指明类型,那多半说的是B-Tree索引,它使用B-Tree数据结构来存储数据,大多数mysql引擎都支持这种索引,存储引擎以不同的方式使用B-Tree索引,性能

也各不相同,各有优劣,例如,myisam使用前缀压缩技术使得索引更小,但InnoDB则按照原数据格式进行存储.再如MyISAM索引通过数据的物理位置引用被索引的行,而

InnoDB则根据主键引用被索引的行.

B-Tree通常意味着所有的值都是按照顺序存储的,并且每一个叶子页到根的距离相同,B-Tree索引能够加快访问数据的速度,因为存储引擎不再需要进行全表扫描来获取

需要的数据,取而代之的是从索引的根节点开始进行搜索,根节点的槽中存放了指向子节点的指针,存储引擎根据这些指针向下层查找.通过比较节点页的值和要查找的值可以

找到合适的指针进入下层子节点,这些指针实际上定义了子节点页中值的上限与下限,最终存储引擎要么是找到对应的值,要么该记录不存在.

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

直接相关.B-Tree对索引列是顺序组织存储的,所以很合适查找范围数据.例如,在一个基于文本域的索引树上,按字母顺序传递连续的值进行查询是非常合适的,所以像“找出所有以

I到K开头的名字”这样的查找效率会非常高.

可以使用B-Tree索引的查询类型,B-Tree索引适用于全键值、键值范围或者键前缀查找,其中键前缀查找只适用于根据最左前缀的查找.

B-Tree对以下类型的查询有效:

1.全值匹配

2.匹配最左前缀(第一列)

3.匹配列前缀(第一列)

4.匹配范围值(第一列)

5.精确匹配某一列并范围匹配另外一列

6.只访问索引的查询

关于B-Tree索引的限制:

1.如果不是按照索引的最左列开始查找,则无法使用索引.

2.不能跳过索引列

3.如果查询中有某个列的范围查询,则其右边所有列都无法使用索引优化查找,例如有查询条件where last_name='smith' and first_name like 'j%' and dob='1976-12-23',

这个查询只能使用索引的前两列,因为这里的like是一个范围条件(但是服务器可以把其余列用于其他目的).如果范围查询列值的数量有限,那么可以通过使用多个等于

条件来代替范围条件.

二.哈希索引

哈希索引基于哈希表实现,只有精确匹配索引所有列的查询才有效,对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码,哈希码是一个较小的值,并且不同的键值

的行计算出来的哈希码也不一样,哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针,在MySQL中,只有Memory引擎显式支持哈希索引.这

也是Memory引擎表默认的索引类型,Memory引擎同时也支持B-Tree索引. 值得一提的是,Memory引擎是支持非唯一哈希索引的,这在数据库世界里面是比较与众不同的,如果

多个列的哈希值相同,索引会以链表的方式存放多个记录指针到同一哈希条目中.

假如有下列表:

create table testhash(

fname varchar(50) not null,

lname varchar(50) not null,

key using hash(fname)

) engine=memory;

表中包含如下数据:

select * from testhash;

fname   lname

Arjen     Lentz

Baron    Schwartz

Peter     Zaitsev

Vadim    Tkachenko

假设索引使用假想的哈希函数f(),它返回下面的值(都是演示数据)

f('Arjen')=2323

f('Baron')=7437

f('Peter')=8784

f('Vadim')=2458

则哈希索引的数据结构如下:

槽         值

2323     指向第一行的指针

2458     指向第四行的指针

7437     指向第二行的指针

8784     指向第三行的指针

注意每个槽的编号是顺序的,但是数据行不是.现在我们讲解一下下面查询语句的查询过程

select lname from testhash where fname='Peter';

mysql先计算“Peter”的哈希值,并使用该值寻找对应的记录指针,因为f('Peter')=8784,所以mysql在索引中查找8784,可以找到指向第3行的指针,

最后一步是比较第三行的值是否为‘Peter’,以确保就是要查找的行.

因为索引自身只需存储对应的哈希值,所以索引的结构十分紧凑,这也让哈希索引查找的速度非常快.然而,哈希索引也有他的限制,如下:

1.哈希索引只包含哈希值与行指针,而不存储字段值,所以不能使用索引中的值来避免读取行,不过,访问内存中的行的速度很快,所以大部分情况下这一点对性能的

影响并不明显.

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

3.哈希索引也不支持部分索引列匹配查找,因为哈希索引始终是使用索引列的全部内容计算哈希值的

4.哈希索引只支持等值比较查询,包括=,IN(),<=>,也不支持任何范围查询,

5.访问哈希索引的数据非常快,除非有很多哈希冲突(不同的索引列值却有相同的哈希值),当出现哈希冲突的时候,存储引擎必须遍历链表中所有的行指针,逐行进行比较,

直到找到所有符合条件的行

6.如果哈希冲突很多的话,一些索引维护操作的代价也会很高,例如,如果在某个选择性很低(哈希冲突很多)的列上建立哈希索引,那么当从表中删除一行的时候,存储引擎需要遍历

对应哈希值的链表的每一行,找到并删除对应行的应用,冲突越多,代价越大

因为以上的这些限制,所以哈希索引只适用于某些特定的场合,而一旦适合哈希索引,则它带来的性能提升将非常显著.

InnoDB引擎有一个特殊的功能叫做“自适应哈希索引”,当InnoDB注意到某些索引值被使用得非常频繁的时候,它会在内存中基于B-Tree索引之上再创建一个哈希索引,这样就让B-Tree索引也

具有哈希索引的一些优点,比如快速的哈希查找.这是一个完全自动的、内部的行为,用户无法控制或者配置,不过如果有必要,完全可以关闭该功能.

三.创建自定义哈希索引

如果存储引擎不支持哈希索引,则可以模拟像InnoDB一样创建哈希索引,这样可以享受一些哈希索引的便利,例如只需要很小的索引就可以为超长的键创建索引.

思路很简单:在B-Tree基础上创建一个伪哈希索引,这和真正的哈希索引不是一回事,因为还是使用B-Tree进行查找,但是它使用哈希值而不是键本身进行索引查找,你需要做的就是

在查询的where子句中手动指定使用哈希函数

下面通过一个例子进行讲解,例如需要存储大量的URL,并且需根据URL进行搜索查找,如果使用B-Tree来存储URL,存储的内容就会很大,因为URL本身都很长,正常情况下会有以下查询:

select id from url where url=''

mysql第四项_mysql数据库的基本介绍与操作(第四篇-mysql索引篇)相关推荐

  1. mysql odbc 数据库连接字符串_MySQL数据库:如何字符串连接操作?

    不管你是做数据分析,还是网络爬虫.Web 开发.亦或是机器学习,你都离不开要和数据库打交道.数据库基本上是结构化数据的集合,通过数据库可以用各种方式轻松地检索,管理和访问数据.如今,像MySQL 这样 ...

  2. Mysql数据库优化技术之配置篇、索引篇 ( 必看 必看 转)

    转自:Mysql数据库优化技术之配置篇.索引篇 ( 必看 必看 ) (一)减少数据库访问 对于可以静态化的页面,尽可能静态化 对一个动态页面中可以静态的局部,采用静态化 部分数据可以生成XML,或者文 ...

  3. Android Studio开发(四)SQLite数据库的DAO标准CRUD操作模拟微信通讯录

    Android Studio开发(四)SQLite数据库的DAO标准CRUD操作模拟微信通讯录 Android Studio开发(四)SQLite数据库的DAO标准CRUD操作模拟微信通讯录 一.任务 ...

  4. mysql反弹提权_MySQL数据库反弹端口连接提权

    [51CTO.com原创稿件]在渗透或者安全评估时,有可能遇到一些比较奇葩的环境,即使通过Mysql root账号和密码获取了webshell,由于无法执行命令.在一般的情况下,也就放弃了.但其实可以 ...

  5. mysql期末考试试卷_MySQL数据库考试试题及答案

    MySQL 数据库考试试题及答案 试题一 一.单项选择题 (本大题共 20 小题,每小题 2 分,共 40 分 ) 在每小题列出的四个备选项中只有一个是符合题目要求的, 请将其代码填写在题 后的括号内 ...

  6. mysql的crud语句_MySQL数据库CRUD语句快速入门

    本文目录: Day11 SQL语句 sql语句,一种用于操作数据库的语言 数据库, 简单地理解为硬盘上的文件, 可以存放数据 sql 语句大致可以分类两大类 进入数据库的方法: 1. 命令行代码: 进 ...

  7. mysql 导出dmp文件_Mysql数据库的各种命令:

    一.连接MYSQL 格式: mysql -h主机地址 -u用户名 -p用户密码 1.连接到本机上的MYSQL. 首先打开DOS窗口,然后进入目录mysqlbin,再键入命令mysql -u root ...

  8. mysql 导出dmp文件_MySQL数据库基础讲解

    # 简介 MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),使用最常用的数据库管理语言(SQL)进行数据库管理. MySQL是开放源代码的,因此任何人都可以在General Publi ...

  9. mysql text字段导出_Mysql数据库的各种命令:

    一.连接MYSQL 格式: mysql -h主机地址 -u用户名 -p用户密码 1.连接到本机上的MYSQL. 首先打开DOS窗口,然后进入目录mysqlbin,再键入命令mysql -u root ...

最新文章

  1. 如何实现phpcms v9_4X版本tag的伪静态?
  2. Error:java: Compilation failed: internal java compiler
  3. 如何用java语言实现C#中的ref关键字(按引用传递参数)的效果
  4. hexo的yelee主题使用katex引擎(markdown渲染加速)
  5. 基于OAuth2的认证(译)
  6. C语言程序设计二期末考试,9第二学期期末考试《C语言程序设计》A
  7. php 5.2.17 中文乱码,php5.2 Json中文乱码解决方法
  8. Python 迭代器和 C++ 迭代器,最大的不同竟然是......
  9. 专业测试油耗的软件,油耗软件app哪个好_检测汽车油耗的软件_油耗记录软件车机版...
  10. PostgreSQL更改表格的owner
  11. 人脸识别、二维码电子签到,让会议会展入场更加智能!
  12. 音视频技术开发周刊 | 274
  13. python爬斗鱼直播房间名和主播名_斗鱼爬虫,爬取颜值频道的主播图片和名字
  14. 曾国藩《挺经》卷十七藏锋
  15. 使用HTML写一个完整的注册页面
  16. Chrome 无法显示网页 错误码:STATUS_INVALID_IMAGE_HASH
  17. 【Pytorch】tensor类型数据.squeeze()和.unsqueeze()函数的简明教程(一看就会)
  18. 终于有人把“计算机底层原理“整理出来了
  19. Oracle数据库导入导出emp文件
  20. 攻防世界 Misc高手进阶区 6分题 北京地铁

热门文章

  1. 嵌入式linux svn,Linux下配置subversion使其支持svn+ssh方式访问
  2. Linux6.5图形模式安装,CentOS 6.5弹性云服务器如何安装图形化界面
  3. 深度学习之基于CNN和VGG19实现灵笼人物识别
  4. 计算机组成原理主存储器知识点,计算机组成原理(存储器).ppt
  5. 升级鸿蒙系统照片,华为鸿蒙系统照片出炉,神似EMUI,海内外花粉沸腾了
  6. oracle linux查看磁盘,fdisk命令_Linux fdisk命令使用详解:查看磁盘使用情况与磁盘分区...
  7. 线程的run()方法带参情况
  8. 深度学习之循环神经网络(3)梯度传播
  9. python爬虫拉取豆瓣Top250数据
  10. 深度学习资料汇总(满满的干货)