0
点赞
收藏
分享

微信扫一扫

MySQL中索引与算法

前言

该文章所用到的表结构:

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for svip
-- ----------------------------
DROP TABLE IF EXISTS `svip`;
CREATE TABLE `svip` (
`vip_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '会员编号',
`vip_name` varchar(10) NOT NULL DEFAULT '' COMMENT '会员姓名',
`vip_cardID` varchar(18) NOT NULL COMMENT '会员身份证号码',
`vip_iphone` varchar(10) NOT NULL COMMENT '会员电话',
`vip_address` varchar(50) NOT NULL COMMENT '会员住址',
`vip_mark` text NOT NULL COMMENT '会员备注信息',
PRIMARY KEY (`vip_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

来源

       MySQL索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存,如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录。表里面的记录数量越多,这个操作的代价就越大,如果作为搜索条件的列上已经创建了索引,MySQL中索引与算法_数据。如果表中有1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍。
在使用like的时候,如果使用‘%%’,会不会用到索引呢?

EXPLAIN SELECT * FROM svip WHERE vip_id LIKE '%1%'

查询结果possible_key为空,表示没有用到索引:
MySQL中索引与算法_数据_02
使用到了主键索引:
MySQL中索引与算法_mysql_03
综上,MySQL在使用like查询的时候只使用后面的%时,才会使用到索引。

索引分类:

PRIMARY 主键:唯一且不能为空。
INDEX:普通的索引。
UNIQUE 唯一索引:不允许有重复。
FULLTEXT 全文索引:用于在一篇文章中,检索文本信息的。

各有什么区别?各适用于什么场合?
举个例子来说,比如你在为某商场做一个会员卡的系统,这个系统有一张会员表,表结构如上前言,各字段含义:
会员编号 INT
会员姓名 VARCHAR(10)
会员身份证号码 VARCHAR(18)
会员电话 VARCHAR(10)
会员住址 VARCHAR(50)
会员备注信息 TEXT

那么这个会员编号,作为主键,使用 PRIMARY
会员姓名如果要建索引的话,那么就是普通的 INDEX
会员身份证号码如果要建索引的话,那么可以选择 UNIQUE (唯一的,不允许重复)
会员备注信息如果要建索引的话,可以选择 FULLTEXT,全文搜索。
       不过 FULLTEXT 用于搜索很长一篇文章的时候,效果最好,用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以。MySQL从3.23.23版开始支持全文索引和全文检索,在MySQL中,全文索引的索引类型为FULLTEXT。全文索引可以在CHAR、VARCHAR或者TEXT类型的列上创建。它可以通过CREATE TABLE命令创建,也可以通过ALTER TABLE或CREATE INDEX命令创建。对于大规模的数据集,通过ALTER TABLE(或者CREATE INDEX)命令创建,全文索引要比把记录插入带有全文索引的空表更快。

MySQL添加索引方法

索引算法:

       我们在MySQL中常用两种索引算法BTree和Hash,两种算法检索方式不一样,对查询的作用也不一样。
       BTree索引是MySQL数据库中最常用的索引算法,因为它不仅可以被用在​​​=,>,>=,<,<=和between​​​这些比较操作符上,而且还可以用于like操作符,只要它的查询条件是一个不以通配符开头的常量。
       Hash索引只能用于对等比较,例如“=”,“IN”,“<=>”(等价于=)操作符。由于是一次定位数据,不像BTree索引需要从根节点到枝节点,最后才能访问到页节点这种多次访问,所以检索效率远高于BTree索引,但Hash索引仅仅能满足“=”,“IN”,“<=>”查询,不能使用范围查询。
MySQL中索引与算法_数据_04
例如这样也使用了索引:
MySQL中索引与算法_数据_05
Hash索引的几个缺点以至于工作中不经常使用:

  1. Hash索引仅仅能满足“=”,“IN”,“<=>”查询,不能使用范围查询
  2. 联合索引中,Hash索引不能利用部分索引键查询
  3. Hash索引无法避免数据的排序操作
  4. Hash索引任何时候都不能避免表扫描
  5. Hash索引遇到大量Hash值相等的情况后性能并不一定会比BTree高


小知识:
"<=>"符号其实在数学中叫做“等价于”,代表”推理中左边可以推出右边,右边也可推出左边”的意思,P=>Q:若P则Q,P<=Q:若Q则P,P<=>Q:若P则Q且若Q则P。接下来看一下我的测试,在库中建一张test表,建一个hash索引num1_hash。
表结构跟数据:

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for test
-- ----------------------------
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`num1` int(11) DEFAULT NULL,
`num2` int(11) DEFAULT NULL,
`num3` decimal(14,2) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `num1_hash` (`num1`) USING HASH
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

-- ----------------------------
-- Records of test
-- ----------------------------
INSERT INTO `test` VALUES ('1', '1', '1', '1.00');
INSERT INTO `test` VALUES ('2', '2', '2', '2.00');
INSERT INTO `test` VALUES ('3', '3', '3', '3.00');
INSERT INTO `test` VALUES ('4', '4', '4', '4.00');
INSERT INTO `test` VALUES ('5', '5', '5', '5.00');

查询结果:
MySQL中索引与算法_数据_06
接下来再看看hash索引对<,<=,>,>=符号是否支持:
MySQL中索引与算法_数据_07
MySQL中索引与算法_mysql_08
MySQL中索引与算法_mysql_09
MySQL中索引与算法_数据_10
可以看出在<=2与<3是能命中索引的,在<=3与<4是全表扫描,所以<,>等符号也不是完全不能命中索引,跟btree测试结果一样,但是对查询的优化有没有用还没有研究过,后续会继续研究一下进行补充。


举报

相关推荐

0 条评论