志在峰巅的攀登者,不会陶醉在沿途的某个脚印之中,在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天、每周,都会留下一些脚印,就是这些创作的内容,有一种执着,就是不知为什么,如果你迷茫,不妨来瞅瞅码农的轨迹。

  • 优美的音乐节奏带你浏览这个效果的编码过程
  • 坚持每一天,是每个有理想青年的追求
  • 追寻年轻人的脚步,也许你的答案就在这里
  • 如果你迷茫 不妨来瞅瞅这里

我们这里有一张用户表,建表语句如下

CREATE TABLE `t_user`(`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID' ,`id_card` VARCHAR(32) DEFAULT NULL COMMENT '用户身份证' ,`u_name` VARCHAR(32) DEFAULT NULL COMMENT '用户姓名' ,`u_phone` VARCHAR(32) DEFAULT NULL COMMENT '用户电话' ,`u_password` VARCHAR(200) DEFAULT NULL COMMENT '用户密码' ,`u_age` INT(11) DEFAULT NULL COMMENT '用户年龄' ,`u_male` TINYINT(1) DEFAULT NULL ,PRIMARY KEY(`id`) ,KEY `id_card`(`id_card`) ,KEY `u_phone`(`u_phone`)
) ENGINE = INNODB

这个表中有三个索引 id 的主键索引、id_card 的身份索引、手机号的索引。

1 字符串 前缀索引

我们在实际业务开发中,会有手机号密码登录的功能,所以会常有查询语句如下:

select * from t_user where u_phone='xxx' and u_password='xxx';

所以我们在 u_phone 上添加了索引,如果不添加索引,这个查询就会走全表扫描,当用户量足够大时,这个查询会足够的慢。


在这里我们为 u_phone 添加的索引,默认是11位长度的(因为手机号一般是11位),MySQL 是支持前缀索引的,所以可以考虑定义字符串的一部分作为索引,如这里我们把 u_phone 原来 11位的长度索引修改为 4 位长度的索引:

#先删除索引
ALTER TABLE t_user DROP INDEX u_phone;
#再修改
alter table t_user add index u_phone2(u_phone(4));

相比于之前的索引,后者 u_phone2 索引结构中每个电话号码字段都只取前 64 个字节,占用的空间会更小,查询速度会更快,但这可能会增加额外的记录扫描次数。

2 普通索引与前缀索引 查询过程分析

如执行以下查询语句

select * from t_user where u_phone='13309090909'

如果我们添加的是普通索引如下:

alter table t_user add index u_phone('u_phone');

那么在执行查询过程:

  1. 从 u_phone 索引树找到满足索引值是’13309090909’的这条记录对应的ID
  2. 然后回表到主键索引上 获取对应ID的这一条数据
  3. 然后在 u_phone 索引树取刚刚查到的位置的下一条记录,判断不浪花兄弟条件,循环结束。

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

如果我们使用的是前缀索引,如下

alter table t_user add index u_phone2(u_phone(4));

那么在执行查询过程:

  1. 从 u_phone2 索引树找到满足条件的第一个记录ID;
  2. 然后回表到主键上查询获取这一行数据,然后判断出 这条数据中的电话号码是 ‘13309090909’,满足条件,保留数据,否则丢弃这条查询
  3. 然后再去 u_phone2 索引树找到满足条件 ‘1330’ 的ID,然后回表到ID 索引上取整行然后判断,这次值对了,将这行记录加入结果集;
  4. 重复上一步,直到在 u_phone2 上取到的值不是’1330’时,循环结束。

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


当我们再取 u_phone 字段的前5个字节或者是前6个字节来构建索引,查询次数又可能不一样,也就是使用前缀索引,定义好长度,就可以做到既节省空间,又不用额外增加太多的查询 成本。

关键就是定义前缀索引的长度的权衡问题

3 前缀索引的长度的权衡

我们可以先查询这个表中不同手机号码的用户数量

select count(distinct mobile) as L from tb_user;

比如我这个测试表中的查询结果如下:

然后,依次选取不同长度的前缀来看这个值对比一下不同数据的数量:

SELECTcount(DISTINCT LEFT(mobile , 4)) AS L4 ,count(DISTINCT LEFT(mobile , 5)) AS L5 ,count(DISTINCT LEFT(mobile , 6)) AS L6 ,count(DISTINCT LEFT(mobile , 7)) AS L7
FROMtb_user

对比一下,在这里我们可以使用 前缀7个字节,这样区别扫描次数最少,如我们这个表中有 190 个不同的电话号码用户数据,如果使用电话号码的全字段创建索引,有190个不同的值,在查询数据里,扫描电话号码索引表查询到数据,扫描一次。

如果选用前7个字节构建索引数据结构,重复的索引值有 190-124 = 56个,也就是说当查询到前缀正好在这56个重复索引中,需要回表查询56次进行判断。

如果选用前6个字节构建索引数据结构,重复的索引值有 190-78 = 112个,也就是说当查询到前缀正好在这112个重复索引中,需要回表查询112次进行判断。

所以需要选择 前缀7个字节。


完毕

不局限于思维,不局限语言限制,才是编程的最高境界。

以小编的性格,肯定是要录制一套视频的,随后会上传

有兴趣 你可以关注一下 西瓜视频 — 早起的年轻人

MySql 你真的会使用字符串索引吗???相关推荐

  1. mysql修改索引对交易影响吗_MySQL中字符串索引对update的影响分析

    本文分析了mysql中字符串索引对update的影响.分享给大家供大家参考,具体如下: 对某一个类型为varchar的字段添加前缀索引后,基于该子段的条件查询时间基本大幅下降:但对于update操作, ...

  2. mysql字符串索引如何排序_MySQL 建立索引的时候如何排序?

    以下回复可能有需要更正的地方 "表引擎在 innodb 的情况下建立 age.sex 的联合索引即可,innodb 会在建立索引时生成 btree 数据结构,这个数据结构上会隐式的加上主键& ...

  3. mysql中groupby会用到索引吗_开发人员不得不知的MySQL索引和查询优化

    本文主要总结了工作中一些常用的操作及不合理的操作,在对慢查询进行优化时收集的一些有用的资料和信息,本文适合有 MySQL 基础的开发人员. 索引相关 索引基数 基数是数据列所包含的不同值的数量,例如, ...

  4. mysql分别写出3条索引_MySQL3:索引

    什么是索引 索引是对数据库表中一列或者多列的值进行排序的一种结构,所引用于快速找出在某个列中有一特定值的行.不使用索引,MySQL必须从第一条记录开始读完整个表,直到找出相关的行.表越大,查询数据所花 ...

  5. 超详细图解!【MySQL进阶篇】SQL优化-索引-存储引擎

    1. Mysql的体系结构概览 整个MySQL Server由以下组成 Connection Pool : 连接池组件 Management Services & Utilities : 管理 ...

  6. 在Python中查找子字符串索引的5种方法

    在Python中查找字符串中子字符串索引的5种方法 (5 Ways to Find the Index of a Substring in Strings in Python) str.find() ...

  7. mysql业务繁忙时能建索引吗_MySQL DBA面试高频三十问

    原标题:MySQL DBA面试高频三十问 前言 本文主要受众为开发人员,所以不涉及到MySQL的服务部署等操作,且内容较多,大家准备好耐心和瓜子矿泉水. 前一阵系统的学习了一下MySQL,也有一些实际 ...

  8. Mysql中SQL语句不使用索引的情况

    Mysql中SQL语句不使用索引的情况 MySQL查询不使用索引汇总 众所周知,增加索引是提高查询速度的有效途径,但是很多时候,即使增加了索引,查询仍然不使用索引,这种情况严重影响性能,这里就简单总结 ...

  9. 一次MySQL线上慢查询分析及索引使用

    本文由作者郑智辉授权网易云社区发布. 0.前言 本文通过分析线上MySQL慢查询日志,定位出现问题的SQL,进行业务场景分析,结合索引的相关使用进行数据库优化.在两次处理问题过程中,进行的思考. 1. ...

最新文章

  1. 有空时深入阅读这两篇文章
  2. nodejs 向mongodB获取指定数目的数据
  3. 什么是 DDos 攻击
  4. 10.31NOIP模拟赛解题报告
  5. Java微信公众平台获取签名
  6. Matlab guide菜单+快捷菜单的使用
  7. Mysql探究与学习大纲--主要是为了自己复习方便
  8. 中山计算机辅助设计报考,中山模具设计与CNC数控编程专业
  9. java 反复器_java集合类中的枚举器(反复器)
  10. 解决Eclipse 鼠标悬停提示框是黑色的
  11. gmp新附录 计算机系统,GMP新附录:计算机系统
  12. 阳明心学解析——心学本质关系连接
  13. JS中alert的三种使用方式
  14. android 录制视频模糊,安卓手机录制视频不清晰是什么原因?_科技数码通
  15. 牛逼!女生怒考 692 分,想当程序员,卷了卷了。。
  16. 亚马逊多账号防关联的解决方式
  17. 内存溢出(out of memory)是内存不足吗?Outofmemory error怎么解决?
  18. scJoint integrates atlas-scale single-cell RNA-seq and ATAC-seq data with transfer learning
  19. 第一次安装mysql怎么样启动_CentOS第一次安装MySQL的完整步骤
  20. 昨日一宿春雨下,我想永远是清明

热门文章

  1. 除了 Tensorflow、PyTorch ,还有哪些深度学习框架值得期待?
  2. 硬核!有人开源了一套呼吸机方案!
  3. Scikit-Learn 新版本发布!一行代码秒升级
  4. 联机手写汉字识别,基于新型RNN网络结构的方法
  5. 快速精准的人头检测,代码已开源
  6. 笔记 | 机器学习《概率图模型》,手推笔记已186页!
  7. numpy实现全连接网络进行mnist训练测试
  8. 当常规的算法都山穷水尽之后,你可以试试python中的SMOTE算法
  9. 永恒之蓝(MS17-010)补丁KB号
  10. Windows修改远程桌面端口方法步骤