一,mysql索引

mysql对索引的定义就是:索引是帮助高效获取数据的数据结构,

1.mysql中索引的使用

mysql索引类型

普通索引

其实就是普通的键,能加快查询速度

唯一索引

加快查询,但是索引列值必须唯一,可以为null

主键索引

唯一索引的特例,列值不可为null

全文索引

对文本内容进行查询时,能加快速度

单列索引

就是常见的一个列字段的索引

组合索引

多个列字段组成一个索引,在组合搜索中效率快

mysql中的索引操作

1.创建索引

--创建普通索引

create index index_name on table_name(col_name)

--创建唯一索引

create unique index index_name on table_name(col_name)

--创建组合索引

--遵循“最左前缀”原则,把最常用作为检索或排序的列放在最左,依次递减,组合索引相当于建立了col1,col1col2,col1col2col3三个索引,而col2或者col3是不能使用索引的。

create index index_name on table_name(col_name1,col_name2,col_name3)

--创建唯一组合索引

create unique index index_name on table_name(col_name1,col_name2)

复制代码

2.通过修改表结构创建索引

alter table table_name add index index_name(col_name)

--创建全文索引

ALTER TABLE 'table_name' ADD FULLTEXT INDEX ft_index('col');

复制代码

3.删除索引

drop index index_name on table_name

复制代码

二,mysql索引底层数据结构

mysql中的索引是在存储引擎中实现的而不是在服务器端实现的,所以,不同存储引擎支持的索引可能也会有所不同

我们在开头就提到,索引是mysql高效获取数据的数据结构,也就是说,索引其实归根揭底也是一种数据结构

1.猜想索引的数据结构

索引绝大多数情况都是用在查询操作当中,那么我们列举下我们知道的查找算法

1. 顺序查找?

顺序查找复杂度是O(n),在数据大的情况下,这种算法的查询表现是十分糟糕的

复制代码

2. 二叉树查找?

如果是二叉搜索树:有可能会出现深度过大的左偏树或者右偏树,这样时间复杂度就会有O(logN)变为O(N)

如果是二叉搜索树的进化版平衡二叉树又或者红黑数呢:在数据量大的情况下,基于两个子树的二叉树还是会显得深度过大

复制代码

3.多叉树?

目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构

复制代码

2.基于多叉树的索引实现

在mysql中不同存储引擎对索引的实现也不同,本文主要讨论MyISAM和InnoDB两个存储引擎的索引实现方式。

MyIsam索引实现(非聚集索引)

MyIsam引擎使用B+树来实现索引,在B+树的叶子节点数据域中存放的mysql表数据记录的地址

这里设表一共有三列,假设我们以Col1为主键,则图8是一个MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件仅仅保存数据记录的地址。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。如果我们在Col2上建立一个辅助索引,则此索引的结构如下图所示:

在进行sql查询时,会根据查询语句中的索引条件,在b+树中找到相应的叶子节点,取出相应的数据地址,然后获取相关表记录

innerDB索引实现(聚集索引)

虽然innerDB也使用b+树作为索引结构,但是实现方式和myisam不同

在主索引中,b+树叶子节点数据域中存储的是数据库表相关列的完整记录

在辅助索引中,b+树叶子节点存储的是主键的值

这种就是聚集索引

聚集索引在进行主索引查询时效率很高,直接找到相关叶子节点就可以找到相关数据记录,非聚集索引还需要根据数据地址去寻找数据记录

但是聚集索引在辅助索引查询时效率低非聚集索引低,因为需要检索两次b+树,第一次找到主键值,第二次根据主键值找到相关记录

为什么要使用多叉树实现呢?

我们知道平衡的二叉查找树可以做到树的高度小于普通的二叉查找树且查询效率可以达到O(logN),但是,当在大量数据存储在磁盘时,我们并不能一下就将这些数据全部都加载到内存中,而是一页一页的加载,每一磁盘页的数据对应一个树的节点,当树的节点过多时,会造成大量磁盘IO操作,最坏情况下就是树的深度,平衡二叉树由于树深度过大而造成磁盘IO读写过于频繁,进而导致效率低下。

所以,这就是使用平衡的多路查找树的原因,既可以降低树的高度,又能保证查询效率在O(logN)

多叉树简述

b树

b树是最普通的一类多叉树,一个m阶的b树具有如下几个特征:

b树中所有节点的的子节点数的最大值称为b树的阶

一个节点有k个孩子,那么必有k-1个关键字才能将子节点划分为k个子集

根结点至少有两个子女。

每个中间节点都包含k-1个元素和k个孩子,其中 ceil(m/2) ≤ k ≤ m

每一个叶子节点都包含k-1个元素,其中 ceil(m/2) ≤ k ≤ m

所有的叶子结点都位于同一层。

每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域划分

每个结点的结构为:(n,A0,K1,A1,K2,A2,… ,Kn,An)

其中,Ki(1≤i≤n)为关键字,且Ki

Ai(0≤i≤n)为指向子树根结点的指针。且Ai所指子树所有结点中的关键字均小于Ki+1。

n为结点中关键字的个数,满足ceil(m/2)-1≤n≤m-1。

例如:

三阶b树:最大子节点数量为3,节点关键字为2个

查询操作

以上图为例:若查询的数值为5:

第一次磁盘IO:在内存中定位(与17、35比较),比17小,左子树;

第二次磁盘IO:在内存中定位(与8、12比较),比8小,左子树;

第三次磁盘IO:在内存中定位(与3、5比较),找到5,终止。

整个过程中,我们可以看出:比较的次数并不比二叉查找树少,尤其适当某一节点中的数据很多时,但是磁盘IO的次数却是大大减少。比较是在内存中进行的,相比于磁盘IO的速度,比较的耗时几乎可以忽略。所以当树的高度足够低的话,就可以极大的提高效率。相比之下,节点中的元素多点也没关系,仅仅是多了几次内存交互而已,只要不超过磁盘页的大小即可。现在重点关注的就是磁盘IO的次数

插入操作

若被插入节点的关键字个数 < m-1 ,则直接插入

若被插入节点的关键字个数等于m-1,则会引起该节点分裂,将节点中间值插入到该节点的父节点

重复上述工作,最坏情况一直分裂到根结点,建立一个新的根结点,整个B树增加一层。

eg:插入4

会引起节点分裂,将中间值4提到父节点,若扔引起分裂,重复操作

之所以要分裂,其实就是维护多叉树平衡的一个性质,相当于平衡树中的旋转

删除操作

B树中关键字的删除比插入更复杂,在这里说下跟b树插入节点类似的一种删除方法:

eg:删除11

但是删除后12只有右子节点了,需要判断其左右兄弟结点中有“多余”的关键字,即:原关键字个数n>=ceil(m/2) - 1

右子节点分裂

补充:

B树主要用于文件系统以及部分数据库索引,例如: MongoDB。而大部分关系数据库则使用B+树做索引,例如:mysql数据库;

从查找效率考虑一般要求B树的阶数m >= 3;

B-树上算法的执行时间主要由读、写磁盘的次数来决定,故一次I/O操作应读写尽可能多的信息。因此B-树的结点规模一般以一个磁盘页为单位。一个结点包含的关键字及其孩子个数取决于磁盘页的大小。

b+树

B+树是B树的变种,有着比B树更高的查询效率

特征:

有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每个元素不保存数据,只用来索引,所有数据

都保存在叶子节点。

所有的叶子结点中包含了全部元素的信息,及指向含这些元素记录的指针,且叶子结点本身依关键字的大小

自小而大顺序链接。

所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。

eg:三阶b+树

查找

B+树通常有两个指针,一个指向根结点,另一个指向关键字最小的叶子结点。因些,对于B+树进行查找两种运算:一种是从最小关键字起顺序查找,另一种是从根结点开始,进行随机查找。

B+树相比B树的优势:

b+树中间节点存储的是数据在叶节点的索引,可以包含的关键字更多,单一节点存储更多的元素,使得查询的IO次数更少;

所有查询都要查找到叶子节点,查询性能稳定;

所有叶子节点形成有序链表,便于范围查询。

eg:范围查询

b树范围查询:

b+树:

innerDB和myIsam的区别

myIsam

innerDB

索引类型

非聚集索引

聚集索引

索引底层结构

b+树

b树

是否支持事务

是否支持表锁

是否支持行数

是否支持外键

是否支持全文索引

是否支持hash索引

适用操作

大量select

大量insert、delete和update下

三,补充

哈希索引

只有memory(内存)存储引擎支持哈希索引,哈希索引用索引列的值计算该值的hashCode,然后在hashCode相应的位置存执该值所在行数据的物理位置,因为使用散列算法,因此访问速度非常快,但是一个值只能对应一个hashCode,而且是散列的分布方式,因此哈希索引不支持范围查找和排序的功能,但是hash适用于 = 或者 in的等值查询

mysql+全文本检索的列,mysql索引相关推荐

  1. mysql 全文本检索的列_Mysql 全文本检索

    mysql 全文索引 注意 并非所有的引擎都支持 全文检索 mysql最常用的引擎 INnodb 和 myisam 后者支持全文检索 前者不支持 创建表的时候指定要检索列 CREATE TABLE T ...

  2. mysql 全文本检索的列_排序数据列以检索MySQL中的最大文本值

    为此,您可以将ORDER BY与一些聚合函数right()一起使用.让我们首先创建一个表-create table DemoTable1487 -> ( -> StudentCode te ...

  3. mysql全表扫描和用索引的区别

    全表扫描的意思就是要把表中所有数据过一遍才能显示数据结果,索引扫描就是索引,只需要扫描一部分数据就可以得到结果, 打个比方吧,在新华字典中,如果没有拼音或笔画索引,当我们查找"做" ...

  4. mysql not in 多列,MySQL中的多列外键?

    I have a table that has a primary key consisting of two columns (product_id, attribute_id). I have a ...

  5. mysql 临时列_如何在MySQL中列出临时表列?

    要列出MySQL中的临时表列,让我们首先创建一个临时表. 这是一个例子.我们创建了一个临时表,其中包含一些列,其中包括学生的详细信息-mysql> CREATE TEMPORARY TABLE  ...

  6. 尽量使用覆盖索引,避免select * || 用or分割开的条件,如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到|| 如果MySQL评估使用索引比全表更慢,则不使用索引

    尽量使用覆盖索引,避免select * 尽量使用覆盖索引(只访问索引的查询(索引列完全包含查询列)),减少select * 7). 用or分割开的条件,如果or前的条件中的列有索引,而后面的列中没有索 ...

  7. mysql 主表某一列 小于某一个表的两列之和_关于MySQL索引知识与小妙招

    1.1 索引的优点 大大减少了服务器需要扫描的数据量,加快数据库的检索速度 帮助服务器避免排序和临时表 将随机io变成顺序io 1.2 索引的用处 速查找匹配WHERE子句的行 从considerat ...

  8. mysql 虚拟列索引_使用MySQL 5.7虚拟列提高查询效率

    原标题:使用MySQL 5.7虚拟列提高查询效率 导读 翻译团队:星耀队@知数堂 团队成员:星耀队-芬达,星耀队-顺子,星耀队-M哥 原文出处:https://www.percona.com/blog ...

  9. mysql 离散度_【MySQL】索引原理(四):创建索引的几点建议,列的离散度,前缀索引...

    我们容易有以一个误区,就是在经常使用的查询条件上都建立索引,索引越多越好,那到底是不是这样呢? 因为索引对于改善查询性能的作用是巨大的,所以我们的目标是尽量使用索引.但这并不意味着索引越多越好,因为索 ...

最新文章

  1. WCF 改成 restful api
  2. ssh作业批改系统_如何看待「全国至少十省份叫停家长批改作业」?能否从根源解决问题?...
  3. 《梦断代码》读书笔记
  4. jsoup抓取网页报错UnsupportedMimeTypeException
  5. c语言长整数转化为16进制字符串,一个30位的字符串十进制长整数怎么转换为对应的十六进制和八进制...
  6. flex简单常用笔记
  7. [mysql] Incorrect string value: '\xE4\xBC\x9A\xE5\x91\x98' for column 'name' at row 1
  8. Django之POST GET与前后端交互
  9. 收藏 | 关于Mac Dock的10 个隐藏终端命令
  10. MongoDB中文问题
  11. 搭建 Ubuntu 可视化界面
  12. 斐波那契数列(费氏数列)
  13. usb摄像头android录像软件,USB摄像头app
  14. Java EE之FreeMarker前度模板引擎的使用
  15. python内置对象相关方法汇总
  16. 红米note5手机插u盘没反应_U盘插到充电器上会损坏?爆炸?实验结果没让我失望...
  17. 津津的储蓄计划 NOIp提高组2004
  18. Axure制作微信APP原型(三):消息+个人模块----聊天、浮窗、登录设备、个人主页、更多信息
  19. Android签名打包报错:Conversion to Dalvik fromat failed with error 1
  20. Wolfram Alpha 算微积分指令集合

热门文章

  1. otn系统中常用的电层_WDM与OTN浅谈
  2. c++语言socket udp聊天程序,使用C/C++实现Socket聊天程序
  3. java中如何引用非静态变量_java为什么不能从静态环境引用非静态变量?
  4. mysql完整性约束命名_第5章--MySQL索引与完整性约束.ppt
  5. Spring DI(依赖注入)Xml篇
  6. quartz实现每周一至周五 非法定节假日 每天9:30-11:30,13:00-15:00执行定时任务
  7. android中sharedPreferences的用法
  8. 论文阅读:Single Image Dehazing via Conditional Generative Adversarial Network
  9. BZOJ 2287 POJ Challenge 消失之物
  10. jQuery全局Ajax事件处理器