问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

mysql 有几种索引

发布网友 发布时间:2022-04-24 17:45

我来回答

3个回答

热心网友 时间:2022-04-07 16:21

如大家所知道的,Mysql目前主要有以下几种索引类型:FULLTEXT,HASH,BTREE,RTREE。
那么,这几种索引有什么功能和性能上的不同呢?
FULLTEXT
即为全文索引,目前只有MyISAM引擎支持。其可以在CREATE TABLE ,ALTER TABLE ,CREATE INDEX 使用,不过目前只有 CHAR、VARCHAR ,TEXT 列上可以创建全文索引。值得一提的是,在数据量较大时候,现将数据放入一个没有全局索引的表中,然后再用CREATE INDEX创建FULLTEXT索引,要比先为一张表建立FULLTEXT然后再将数据写入的速度快很多。
全文索引并不是和MyISAM一起诞生的,它的出现是为了解决WHERE name LIKE “%word%"这类针对文本的模糊查询效率较低的问题。在没有全文索引之前,这样一个查询语句是要进行遍历数据表操作的,可见,在数据量较大时是极其的耗时的,如果没有异步IO处理,进程将被挟持,很浪费时间,当然这里不对异步IO作进一步讲解,想了解的童鞋,自行谷哥。
全文索引的使用方法并不复杂:
创建ALTER TABLE table ADD INDEX `FULLINDEX` USING FULLTEXT(`cname1`[,cname2…]);
使用SELECT * FROM table WHERE MATCH(cname1[,cname2…]) AGAINST ('word' MODE );
其中, MODE为搜寻方式(IN BOOLEAN MODE ,IN NATURAL LANGUAGE MODE ,IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION / WITH QUERY EXPANSION)。
关于这三种搜寻方式,愚安在这里也不多做交代,简单地说,就是,布尔模式,允许word里含一些特殊字符用于标记一些具体的要求,如+表示一定要有,-表示一定没有,*表示通用匹配符,是不是想起了正则,类似吧;自然语言模式,就是简单的单词匹配;含表达式的自然语言模式,就是先用自然语言模式处理,对返回的结果,再进行表达式匹配。
对搜索引擎稍微有点了解的同学,肯定知道分词这个概念,FULLTEXT索引也是按照分词原理建立索引的。西文中,大部分为字母文字,分词可以很方便的按照空格进行分割。但很明显,中文不能按照这种方式进行分词。那又怎么办呢?这个向大家介绍一个Mysql的中文分词插件Mysqlcft,有了它,就可以对中文进行分词,想了解的同学请移步Mysqlcft,当然还有其他的分词插件可以使用。
HASH
Hash这个词,可以说,自打我们开始码的那一天起,就开始不停地见到和使用到了。其实,hash就是一种(key=>value)形式的键值对,如数学中的函数映射,允许多个key对应相同的value,但不允许一个key对应多个value。正是由于这个特性,hash很适合做索引,为某一列或几列建立hash索引,就会利用这一列或几列的值通过一定的算法计算出一个hash值,对应一行或几行数据(这里在概念上和函数映射有区别,不要混淆)。在java语言中,每个类都有自己的hashcode()方法,没有显示定义的都继承自object类,该方法使得每一个对象都是唯一的,在进行对象间equal比较,和序列化传输中起到了很重要的作用。hash的生成方法有很多种,足可以保证hash码的唯一性,例如在MongoDB中,每一个document都有系统为其生成的唯一的objectID(包含时间戳,主机散列值,进程PID,和自增ID)也是一种hash的表现。额,我好像扯远了-_-!
由于hash索引可以一次定位,不需要像树形索引那样逐层查找,因此具有极高的效率。那为什么还需要其他的树形索引呢?
在这里愚安就不自己总结了。引用下园子里其他大神的文章:来自 14的路 的MySQL的btree索引和hash索引的区别
(1)Hash 索引仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询。
由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样。
(2)Hash 索引无法被用来避免数据的排序操作。
由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;
(3)Hash 索引不能利用部分索引键查询。
对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。
(4)Hash 索引在任何时候都不能避免表扫描。
前面已经知道,Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。
(5)Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。
对于选择性比较低的索引键,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。

愚安我稍作补充,讲一下HASH索引的过程,顺便解释下上面的第4,5条:
当我们为某一列或某几列建立hash索引时(目前就只有MEMORY引擎显式地支持这种索引),会在硬盘上生成类似如下的文件:
hash值 存储地址
1db54bc745a1 77#45b5
4bca452157d4 76#4556,77#45cc…

hash值即为通过特定算法由指定列数据计算出来,磁盘地址即为所在数据行存储在硬盘上的地址(也有可能是其他存储地址,其实MEMORY会将hash表导入内存)。
这样,当我们进行WHERE age = 18 时,会将18通过相同的算法计算出一个hash值==>在hash表中找到对应的储存地址==>根据存储地址取得数据。
所以,每次查询时都要遍历hash表,直到找到对应的hash值,如(4),数据量大了之后,hash表也会变得庞大起来,性能下降,遍历耗时增加,如(5)。
BTREE
BTREE索引就是一种将索引值按一定的算法,存入一个树形的数据结构中,相信学过数据结构的童鞋都对当初学习二叉树这种数据结构的经历记忆犹新,反正愚安我当时为了软考可是被这玩意儿好好地折腾了一番,不过那次考试好像没怎么考这个。如二叉树一样,每次查询都是从树的入口root开始,依次遍历node,获取leaf。
BTREE在MyISAM里的形式和Innodb稍有不同
在 Innodb里,有两种形态:一是primary key形态,其leaf node里存放的是数据,而且不仅存放了索引键的数据,还存放了其他字段的数据。二是secondary index,其leaf node和普通的BTREE差不多,只是还存放了指向主键的信息.
而在MyISAM里,主键和其他的并没有太大区别。不过和Innodb不太一样的地方是在MyISAM里,leaf node里存放的不是主键的信息,而是指向数据文件里的对应数据行的信息.
RTREE
RTREE在mysql很少使用,仅支持geometry数据类型,支持该类型的存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种。
相对于BTREE,RTREE的优势在于范围查找.
各种索引的使用情况
(1)对于BTREE这种Mysql默认的索引类型,具有普遍的适用性
(2)由于FULLTEXT对中文支持不是很好,在没有插件的情况下,最好不要使用。其实,一些小的博客应用,只需要在数据采集时,为其建立关键字列表,通过关键字索引,也是一个不错的方法,至少愚安我是经常这么做的。
(3)对于一些搜索引擎级别的应用来说,FULLTEXT同样不是一个好的处理方法,Mysql的全文索引建立的文件还是比较大的,而且效率不是很高,即便是使用了中文分词插件,对中文分词支持也只是一般。真要碰到这种问题,Apache的Lucene或许是你的选择。
(4)正是因为hash表在处理较小数据量时具有无可比拟的素的优势,所以hash索引很适合做缓存(内存数据库)。如mysql数据库的内存版本Memsql,使用量很广泛的缓存工具Mencached,NoSql数据库redis等,都使用了hash索引这种形式。当然,不想学习这些东西的话Mysql的MEMORY引擎也是可以满足这种需求的。
(5)至于RTREE,愚安我至今还没有使用过,它具体怎么样,我就不知道了。有RTREE使用经历的同学,到时可以交流下!

热心网友 时间:2022-04-07 17:39

MySQL 索引

在MySQL的性能优化中,索引是非常重要的一块,好的索引逻辑可以大大提高MySQL的效率。实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。

本回答来自:MySQL 索引_树懒学堂_一站式数据知识平台

索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索引包含多个列。

热心网友 时间:2022-04-07 19:14

MySQL 8.0 实现了索引的隐藏属性。当然这个特性很多商业数据库早就有了,比如ORACLE,在11g中就实现了。我来介绍下这个小特性。


介绍

INVISIBLE INDEX,不可见索引或者叫隐藏索引。就是对优化器不可见,查询的时候优化器不会把她作为备选。

其实以前要想彻底不可见,只能用开销较大的drop index;现在有了新的方式,可以改变索引的属性,让其不可见,这一操作只更改metadata,开销非常小。


使用场景

我大概描述下有可能使用隐藏索引的场景:

1. 比如,我有张表t1,本来已经有索引idxf1,idxf2,idxf3。我通过数据字典检索到idxf3基本没有使用过,那我是不是可以判断这个索引直接删掉就好了?那如果删掉后突然有新上的业务要大量使用呢?难道我要频繁的drop index/add index吗?这个时候选择开销比较小的隐藏索引就好了。

2. 我的业务只有一个可能每个月固定执行一次的SQL用到这个索引,那选择隐藏索引太合适不过了。

3. 又或者是我想要测试下新建索引对我整个业务的影响程度。如果我直接建新索引,那我既有业务涉及到这个字段的有可能会收到很大影响。那这个时候隐藏索引也是非常合适的。


举例

下面我来简单举例如何使用隐藏索引:

表结构

mysql> create table f1 (id serial primary key, f1 int,f2 int );Query OK, 0 rows affected (0.11 sec)

创建两个索引,默认可见。

索引1,

mysql> alter table f1 add key idx_f1(f1), add key idx_f2(f2);Query OK, 0 rows affected (0.12 sec)Records: 0  Duplicates: 0  Warnings: 0

索引2,

mysql> show create table f1\G*************************** 1. row ***************************       Table: f1Create Table: CREATE TABLE `f1` (  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  `f1` int(11) DEFAULT NULL,  `f2` int(11) DEFAULT NULL,  PRIMARY KEY (`id`),  UNIQUE KEY `id` (`id`),  KEY `idx_f1` (`f1`),  KEY `idx_f2` (`f2`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci1 row in set (0.00 sec)

简单写个造数据的存储过程。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
中山眼科医科的吕林教擅长哪方面治疗,要怎样预约 冰箱冷冻成品区和冷冻生鲜区的区别 东京大学东洋文化研究所前身今世 简单介绍东洋武士文学 东洋西洋区别 追高被套的股票怎么操作? 求助!要有怎样的配置才能玩得起古剑奇谭或仙剑5? 我的配置玩古剑奇谭老重启和卡 高手帮忙看一下怎么解决啊 我的配置玩... 电脑任务栏微信QQ图标怎么消失? qq和微信这样的弹出窗口怎么取消 mysql常见索引有哪些 mysql的索引类型 mysql索引类型有哪些 今日头条发表文章,视频可以赚钱吗 苹果手机型号MQ6M2CH/A是什么意思? IGBT 模块为什么坏一个要同时换两个? 电磁炉大功率的IGBT管H20R1202用什么其他型号可以代替 FP15R12W1T4P这个IGBT模块有国产替换的嘛? FF300R12KS4停产的IGBT模块替换型号是什么? F3L150R12W2H3_B11三电平IGBT模块国产封装替换的有吗? IGbt4On6O用什么替换? 电磁炉IGBT管的代换 电磁炉大功率的IGBT管H20R1202用什么其他型号可以代替? IGBT模块SKM 145GB124D的代换型号 k1120可以用IGBT模块代替吗? IGBT 管上的数字表示什么(H15R1202) 如果没有这型号改换什么样的 富士IGBT模块7mbr100u4b-120-50可以用什么型号替换? 电磁炉的igbt坏了,可以用那些替代 西门子IGBT BSM25GD100D能用那款IGBT的那个型号替代? 逆变焊机IGBT模块DM2G100SH12AE能用SKM100GB128DN代换么.我看这俩模块的电路图都一样.请高手指教 mysql常见的三种存储引擎 MySQL数据库中所支持的3个引擎有哪些? MYSQL的各个索引类型有什么区别? 国际服刺激战场登陆总提示等待200多秒之后登陆,为什么 刺激战场:国际服到底有哪些优势? 想下载国际服刺激战场,应该怎么下载,应该注意什么? javaweb和h5的前端开发有什么区别吗 java ee 和 h5的区别 java和h5那个比较好 h5和java该怎么选择 java还是H5比较有发展前景啊 基础设施基金网下投资者范围包括哪些? HTML5开发app与java开发的区别?? 网下投资者通过什么部门备案 网下投资者询价报价方面,有什么要求? 现在培训H5,java,php哪个好点 哪些投资者可以参与创业板网下申购? 学习html5好还是java好 网下投资者参与网下申购新股后初步询价应符合哪些条件 想问下现在培训java还是h5前端开发比较好呢?