一:概述

  - 我有一个需求是需要邮箱登录的,

  - mysql> select f1, f2 from SUser where email='xxx';

  - 我们知道,如果不在 email 上建立索引,那么将会走全表扫描。

  - 于是,我们有两种建立方式

    - mysql> alter table SUser add index index1(email);       // 普通索引

    - mysql> alter table SUser add index index2(email(6));   // 前缀索引

二:普通索引和前缀索引的区别?

  - 我们看看,他们建立的索引树有什么不同

     -                     

  

  - 从图中你可以看到

    - 由于 email(6) 这个索引结构中每个邮箱字段都只取前 6 个字节(即:zhangs),所以占用的空间会更小,这就是使用前缀索引的优势。

    - 但,这同时带来的损失是,可能会增加额外的记录扫描次数。 
 

三:普通索引和前缀索引查询流程的不同?

    - 举例

      - select id,name,email from SUser where email='zhangssxyz@xxx.com';

    - 普通索引

      - 从索引树找到满足索引值是 'zhangssxyz@xxx.com' 的这条记录,取得 ID2 的值;

      - 到主键上查到主键值是 ID2 的行,判断 email 的值是正确的,将这行记录加入结果集;

      - 取索引树上刚刚查到的位置的下一条记录,发现已经不满足 email='zhangssxyz@xxx.com'的条件了,循环结束。

      - 这个过程中,只需要回主键索引取一次数据,所以系统认为只扫描了一行。

    - 前缀索引

      - 索引树找到满足索引值是 'zhangs' 的记录,找到的第一个是 ID1;

      - 到主键上查到主键值是 ID1 的行,判断出 email 的值不是'zhangssxyz@xxx.com',这行记录丢弃;

      - 取到刚刚查到的位置的下一条记录,发现仍然是’zhangs‘,取出 ID2,再到 ID 索引上取整行然后判断,这次值对了,将这行记录加入结果集;

      - 重复上一步,直到取到的值不是'zhangs'时,循环结束。

      - 在这个过程中,要回主键索引取 4 次数据,也就是扫描了 4 行。

    - 结论

      - 通过这个对比,你很容易就可以发现,使用前缀索引后,可能会导致查询语句读数据的次数变多。

四:区分度

  - 通过上面的测试,我们知道,是否会导致查询变多,主要是建立前缀索引的区分度的选择。

  -  SELECT COUNT(DISTINCT LEFT(column_name, $length)) / COUNT(*) FROM table_name;  // 查询区分度

五: 前缀索引对覆盖索引的影响

  - 使用前缀索引后,无法在使用覆盖索引,面对查询条件,可能需要回表操作。

六:面对字符串,我们也可以采取其他方式存储

  - hash

  - bit 位

  - 倒序

  - 等等

《Mysql - 字符串索引应该如何建立?》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. 利用 Python 尝试采用面向对象的设计方法计算图形面积及周长

    利用 Python 尝试采用面向对象的设计方法.(1)设计一个基类 Shape:包含两个成员函数:def cal_area(): 计算并返回该图形的面积,保留两位小数:def cal_perimete ...

  2. FF,NF,BF

    设计一个可变式分区分配的存储管理方案.并模拟实现分区的分配和回收过程. 对分区的管理法可以是下面三种算法之一: 首次适应算法 循环首次适应算法 最佳适应算法 对于测试样例 : 首地址        大 ...

  3. OpenJudge 1.5.27:级数求和

    描述 已知:Sn= 1+1/2+1/3+…+1/n.显然对于任意一个整数K,当n足够大的时候,Sn大于K. 现给出一个整数K(1<=k<=15),要求计算出一个最小的n:使得Sn>K ...

  4. OpenFOAM中的基本变量快速认知【转载】

    转载自:http://blog.sina.com.cn/s/blog_a0b4201d0102vsf9.html label 实际上就是整型数据的变体,int,OF对它进行了包装,以适应32或64位系 ...

  5. html5、手机端 input 单独打开相机、摄像头、录音功能

    相机:<input type="file" name="image" accept="image/*" capture="u ...

  6. Ionic 的安装运行

    1.学习前准备工作 1.必须得安装 nodejs (建议安装最新的稳定版本) 2.必须有 Angular 基础:https://www.loaderman.com/goods-1047.html 2. ...

  7. Angular 自定义模块以及配置路由实现模块懒加载

    项目目录 创建模块 ng g module module/user --routing ng g module module/article --routing ng g module module/ ...

  8. Greenwich.SR2版本的Spring Cloud Hystrix实例

    之前我们在eureka(参见Greenwich.SR2版本的Spring Cloud Eureka实例)中,服务消费方a-beautiful-client调用服务提供方a-bootiful-clien ...

  9. 总结Lock和synchronized的区别

    1. Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现,Lock是代码层面的实现. 2. Lock可以选择性的获取锁,如果一段时间获取不到, ...

  10. iOS 判断scrollView是否滑动到底部

      判断scrollView有没有滚动到视图的底部,用来判断下拉刷新的时间.等 - (void)scrollViewDidScroll:(UIScrollView *)scrollView1 { CG ...