• 1 建表语句

    CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`id_card` varchar(18) NOT NULL,`email` varchar(50) NOT NULL,PRIMARY KEY (`id`)
    ) ENGINE=InnoDBINSERT INTO `test`.`user`(`id`, `id_card`, `email`) VALUES (1, '321023199303164012', 'wangheling@163.com');
    INSERT INTO `test`.`user`(`id`, `id_card`, `email`) VALUES (2, '321023199003184012', 'wangwu@163.com');
    INSERT INTO `test`.`user`(`id`, `id_card`, `email`) VALUES (3, '321023199003251234', 'wangsan@sina.com');
    INSERT INTO `test`.`user`(`id`, `id_card`, `email`) VALUES (4, '021236199503251235', 'wangsi@163.com');

    user表使用邮箱作为登录账号。

    2 邮箱字段建立索引

    这里我们用登录账号,也就是email字段作为索引。

    2.1 直接给email加索引

    select * from user where email = 'wangheling@163.com'

    2.1.1 执行流程

    因为叶子节点存放的就是email的完整值,在非聚集索引里根据email查到了主键id=1,然后进行回表,这里发生一次回表.

    2.1.2 存在问题

    因为邮箱较长,因为b+tree节点是按页存取的,默认16k,如果键值过长,导致问题就是每页存放的键值数量就较少,会增加树高,增加IO次数。

    2.2 前缀索引email(4)

    select * from user where email = 'wangheling@163.com'

    2.2.1 执行流程

    因为叶子节点只会存放email前四个字节的值,所以在非聚集索引里查到四条记录,还要进行四次回表操作,比对email=‘wangheling@163.com’记录进行筛选。

    2.2.2 存在问题

    因为email长度截取了,那么b+tree每个节点存储键值数量多了,树高就低了,那么带来的问题就是,增加了回表的次数。

    2.3 前缀索引email(6)

    select * from user where email = 'wangheling@163.com'

    2.3.1 执行流程

    因为叶子节点只会存放email前六个个字节的值,所以在非聚集索引里查到一条记录,只要进行一次回表操作,比对email=‘wangheling@163.com’,得到结果。

    2.4 阶段小结

    通过上面三个案例可以得到一个结论:

    使用前缀索引,定义好合适的长度,可以在空间和查询效率取得一个平衡。

    那么这个前缀索引长度如何选取呢?
    建立索引的原则就是选取离散度大的字段,那么我们可以计算使用多少长度离散度大:

    select count(distinct left(filed,length)) from tableName;
    

    我们通过如下sql:

    select count(distinct left(email,4)) as L4,count(distinct left(email,5)) as L5,count(distinct left(email,6)) as L6,count(distinct left(email,7)) as L7,count(distinct left(email,8)) as L8
    from user;
    

    结果如下:

    可以看到当长度为6时,区分度最大,可以email(6)。

    2.5 前缀索引带来其他性能问题

    比如:

    select id, email from user where email = 'wangheling@163.com';
    

    上面这个sql,当我们没有使用前缀索引,利用了覆盖索引,无需回表,而如果使用了前缀索引,因为叶子节点没有保存完整的email信息,那么会进行回表。

    当我们使用前缀索引,就是利用不到覆盖索引,需要回表,所以得根据业务场景来选择是否使用前缀索引。

    3 身份证字段建立索引

    身份证长度为18,不适合作为索引。身份证号码特点:前6位代表地址,中间8位为年月日。

    3.1 前缀索引

    前面谈到前缀索引,就不说了。这里存在问题就是,当维护系统是一个市政系统,因为前6位区分度就不高了,所以需要截取长度要更长,还是浪费空间。

    3.2 倒序存储

    因为身份证后六位区分度高,那么我们可以将身份证倒序存储,然后索引为id_card(6)

    select * from user where id_card = reverse('输入的正序身份证号码');
    

    倒序存储只适用等值查询。

    3.3 哈希

    可以新增一个字段存储身份证号码的哈希值,加上索引,存入身份证时候,对身份证进行crc3()计算,得到的值存入id_card_crc,索引长度为4,因为hash可能会发生碰撞,所以查询时候加上身份证作为筛选条件:

    select * from user where id_card_crc = crc32("输入的身份证号码") and id_card = '输入身份证号';
    

    哈希存储只适用等值查询。

    3.4 身份证号码拆分存储

    可以将区分度高的,比如后六位单独存储。

    4 总结

    对于长度较长的字符串,我们可以这么建立索引:

    • 前缀索引
    • 倒序存储
    • 哈希存储
    • 字段拆分

如何给特殊字符串加索引:如身份证、邮箱等相关推荐

  1. 11 怎么给字符串加索引

    11 怎么给字符串加索引 现在,几乎所有的系统都支持邮箱登录,如何在邮箱这样的字段上建立合理的索引? 用户表定义 mysql> create table SUser( ID bigint uns ...

  2. distinct性能问题_Mysql性能优化:如何给字符串加索引?

    导读 现代大部分的登录系统都支持邮箱.手机号码登录两种方式,那么如何在邮箱或者手机号码这个字符串上建立索引才能保证性能最佳呢? 今天这篇文章就来探讨一下在Mysql中如何给一个字符串加索引才能达到性能 ...

  3. 《MySQL——给长字符串加索引》

    对于长字符串,可用如下方式建立索引: (1)前缀索引 (2)字符串倒叙+前缀索引 (3)添加hash字段+并在hash字段上加索引 (4)字段拆分(一个字段可拆分为两个以上) 假设现在表User 中存 ...

  4. mysql 批量加索引_mysql优化:按期删数据 + 批量insert + 字符串加索引为何很傻

    嗯,犯了一个很低级的错误,最近暴露出来了.html 背景:mysql 1. 内部平台,接口间断性无返回,查询日志注意到失败时,接口耗时达到4000+(正常状态:100+ms)git 2. 增长日志打点 ...

  5. mysql 索引 insert_mysql优化:定期删数据 + 批量insert + 字符串加索引为什么很傻

    嗯,犯了一个很低级的错误,最近暴露出来了. 背景: 1. 内部平台,接口间断性无返回,查询日志注意到失败时,接口耗时达到4000+(正常状态:100+ms) 2. 增加日志打点,在关键步骤插入时间戳, ...

  6. MySQL 怎么给字符串字段加索引?

    怎么字符串字段加索引? 使用前缀索引 SQL语句 结论 : 长度合适的话,确实能够节省空间,又不能增加太多查询成本 问题:如何确定多长的前缀合适呢? 注意:前缀+覆盖索引 不太搭,一个必须要回表,一个 ...

  7. 倒序查10条数据_10 | 怎么给字符串字段加索引?

    现在,几乎所有的系统都支持邮箱登录,如何在邮箱这样的字段上建立合理的索引,是我们今天要讨论的问题. 假设,你现在维护一个支持邮箱登录的系统,用户表是这么定义的: mysql> create ta ...

  8. 怎么给字符串字段加索引?

    现在,几乎所有的系统都支持邮箱登录,如何在邮箱这样的字段上建立合理的索引,是我们今天要讨论的问题. 假设,你现在维护一个支持邮箱登录的系统,用户表是这么定义的: mysql> create ta ...

  9. 22-08-25 MySQL高级(03)MySQL索引、索引演绎、适合加索引的情况、执行计划Explain各字段解释

    "系统,那如果我没有绑定,没有简化,我原先的人生最大的可能是怎么样的",李长生好奇一问.很快系统给出了答案. "如果宿主是小说主角的话,就活个几章" " ...

最新文章

  1. ASP .NET Core Web Razor Pages系列教程四:使用数据库进行交互 entity-framework(MySQL/MariaDB 版)
  2. MyEclipse中删除对Struts、hibernate、spring的支持
  3. 3. Port scanners (端口扫描器 4个)
  4. 搜索2.0:利用用户点击记录改善搜索结果
  5. Android之RxJava(一)
  6. pytorch torch.randn
  7. django进阶05中间件
  8. 深入研读Cache存储的计算
  9. this与static
  10. 安徽大学计算机专硕奖学金,2019年安徽大学新闻传播跨考华东师范大学计算机专硕,总分418,排名第一经验分享!...
  11. SYS/BIOS与SRIO应用实例
  12. php把amr转换成mp3,php 微信amr转mp3的方法
  13. 电工电子技术知识点总结(基本放大电路)
  14. Ubuntu返回上级目录快捷键
  15. 服务器安全防护措施有什么?网络安全实战
  16. 软件工程课程设计项目总结与项目报告
  17. 2019年Q4三星和华为都败了,谁也想不到第一名是它
  18. 老沙电信级项目教程-权限部分(1)
  19. Flash 与 VC 通讯
  20. 把图片按照图片名字分到不同的文件夹中

热门文章

  1. 深入理解 ext4 等 Linux 文件系统
  2. OC 与 Swift 区别
  3. 工欲利其器: sqlyog 智能执行功能详解.(http://my.oschina.net/phpnew/blog/151194)
  4. 计算机组成原理结果分析与实验体会,计算机组成原理实验报告心得体会.docx
  5. python运行快捷键修改_pycharm快捷键、常用设置、配置管理
  6. 多尺度双边滤波及基于小波变换的非线性扩散
  7. matlab中采样函数
  8. 电动吞吐式ISO14443ISO15693多功能IC卡磁条读写器M100接口说明
  9. 911和112成世界通用紧急呼叫电话号码
  10. 【原创开源】网络版二代双通道示波器开源发布,支持电脑,手机和Pad等各种OS平台访问...