MySQL -- 字符串索引

栏目: 数据库 · 发布时间: 5年前

内容简介:原则:
CREATE TABLE SUser(
    id BIGINT UNSIGNED PRIMARY KEY,
    name VARCHAR(64),
    email VARCHAR(64)
) ENGINE=InnoDB;

查询

SELECT id,name,email FROM SUser WHERE email='zhangssxyz@xxx.com';

创建索引

ALTER TABLE SUser ADD INDEX index1(email);
ALTER TABLE SUser ADD INDEX index2(email(6));

index1

MySQL -- 字符串索引

  1. 索引长度: 整个字符串
  2. 从index1索引树找到第一个满足索引值为 zhangssxyz@xxx.com 的记录,取得主键为ID2
    • 聚簇索引 上查找值为ID2的行,判断email的值是否正确( Server层行为 ),将该行记录加入结果集
  3. 获取index1上的下一条记录,发现不满足 email=zhangssxyz@xxx.com ,循环结束
  4. 整个过程,只需要 回表 1次,系统认为只扫描了1行

index2

MySQL -- 字符串索引

  1. 索引长度: 前6个字节
  2. 索引占用的 空间更小 ,增加额外的记录 扫描次数 ,(且不支持 覆盖索引 ,见后面)
  3. 从index2索引树找到第一个满足索引值为 zhangs 的记录,取得主键为ID1
  4. 获取index2上的下一条记录,发现仍然是 zhangs ,取得主键为ID2
  5. 重复上面的步骤,直到index2上取得的值不为 zhangs 为止
  6. 整个过程,需要 回表 4次,系统认为扫描了4行
  7. 假设index2为 email(7) ,满足前缀 zhangss 只有一个,只需要回表一次
    • 使用前缀索引,如果能 定义好长度 ,即能 节省空间 ,又 不会增加太多的查询成本

前缀索引的长度

原则: 区分度 。使用前缀索引一般都会 损失区分度 ,预设一个 可接受的损失比例 ,在该损失比例内,寻找 最短 前缀长度

SELECT
    COUNT(DISTINCT email) AS L,
    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
FROM SUser;

前缀索引与覆盖索引

SELECT id,email FROM SUser WHERE email='zhangssxyz@xxx.com';
  1. 如果使用 index1 ,可以利用 覆盖索引不需要回表
  2. 如果使用 index2 ,就 必须回表 ,获得整行记录后再去判断email字段的值
    • 即使index2为 email(18) (包含了所有信息),还是需要回表
    • 因为系统 不确定前缀索引的定义是否截断了完整信息
    • 因此, 前缀索引是用不上覆盖索引对查询性能的优化

其他手段

场景:前缀的区分度非常差,例如居民身份证(前6位是地址码)

倒序存储

SELECT field_list FROM t WHERE id_card = REVERSE('input_id_card_string');

增加hash字段

ALTER TABLE t ADD id_card_crc INT UNSIGNED, ADD INDEX(id_card_crc);
SELECT field_list FROM t WHERE id_card_crc=CRC32('input_id_card_string') AND id_card='input_id_card_string';
  1. 每次插入新纪录的时候,都需要使用 CRC32() 函数得到校验码
  2. 由于校验码可能会 冲突 ,因此查询语句的条件需要加上id_card( 精确匹配
  3. 索引的长度变为了 4个字节 ,比直接用身份证作为索引所占用的空间小很多

异同点

  1. 不支持范围查询 ,只支持 等值查询
  2. 空间占用
    • 倒序存储:N个字节的索引
    • 增加hash字段:字段+索引
  3. CPU
    • 倒序存储:每次读写都需要额外调用一次 REVERSE 函数,开销比 CRC32 函数略小
    • 增加hash字段:每次读写都需要额外调用一次 CRC32 函数
  4. 查询效率
    • 增加 hash 字段方式的查询性能会 更加稳定 一些
      • CRC32虽然会有一定的冲突概率,但概率非常低,可以认为 平均扫描行数接近1
    • 倒序存储一般会用到 前缀索引 ,这会增加 扫描行数无法利用覆盖索引,必须回表

参考资料

《MySQL实战45讲》

转载请注明出处:http://zhongmingmao.me/2019/01/31/mysql-index-string/

访问原文「MySQL -- 字符串索引」获取最佳阅读体验并参与讨论


以上所述就是小编给大家介绍的《MySQL -- 字符串索引》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

个体与交互

个体与交互

Ken Howard、Barry Rogers / 贾永娜、张凯峰 / 机械工业出版社华章公司 / 2012-3-20 / 45.00元

对敏捷软件开发的关注重点,通常都集中在“机制”方面,即过程和工具。“敏捷宣言”认为,个体与交互的价值要高于过程和工具,但这一点很容易被遗忘。在敏捷开发中,如果你重新将注意力放在人的方面,将会收获巨大利益。 本书展示了如何解决敏捷团队在实际项目中遭遇的问题。同时,本书也是很有实用价值的敏捷用户指南,其中包含的故事、最佳实践方法、经验以及技巧均可应用到实际项目当中。通过逐步实践,你将学会如何让团......一起来看看 《个体与交互》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具