一文简单了解MySQL前缀索引


Posted in MySQL onApril 03, 2022

当要索引的列字符很多时 索引则会很大且变慢

( 可以只索引列开始的部分字符串 节约索引空间 从而提高索引效率 )

原则: 降低重复的索引值

例如现在有一个地区表

area gdp code
chinaShanghai 100 aaa
chinaDalian 200 bbb
usaNewYork 300 ccc
chinaFuxin 400 ddd
chinaBeijing 500 eee

发现 area 字段很多都是以 china 开头的

那么如果以前1-5位字符做前缀索引就会出现大量索引值重复的情况

索引值重复性越低 查询效率也就越高

前缀索引测试

// 创建一个测试表
CREATE TABLE `x_test` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `x_name` varchar(255) NOT NULL,
  `x_time` int(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4145025 DEFAULT CHARSET=utf8mb4

// 添加200万条测试数据
INSERT INTO x_test(x_name,x_time) SELECT CONCAT(rand()*3300102,x_name),x_time FROM x_test WHERE id < 30000;

一文简单了解MySQL前缀索引

200万 测试数据

  • 在无任何索引的情况下随便查询一条
    SELECT * FROM x_test WHERE x_name = '1892008.205824857823401.800099203178258.8904820949682635656.62526521254';查询时间:2.253s

  • 添加前缀索引 ( 以第一位字符创建前缀索引 )
    alter table x_test add index(x_name(1))再次查询相同sql语句
    SELECT * FROM x_test WHERE x_name = '1892008.205824857823401.800099203178258.8904820949682635656.62526521254';查询时间:3.291s
    当使用第一位字符创建前缀索引后 貌似查询的时间更长了
    因为只第一位字符而言索引值的重读性太大了
    200万条数据全以数字开头那么平均20万条的数据都是相同的索引值

  • 重新建立前缀索引 这次以前4位字符来创建
    alter table x_test add index(x_name(4));再次查询相同sql语句
    SELECT * FROM x_test WHERE x_name = '1892008.205824857823401.800099203178258.8904820949682635656.62526521254';查询时间:0.703s
    这次以前4位创建索引 大大减少了索引值的重复性 查询速度从3秒提升到0.7秒

  • 200万条数据都以数字开头 而0-9排列组合7位则可达到千万种组合
    也就是以前7位来做索引则不会出现重复索引值的情况了
    alter table x_test add index(x_name(7));再次查询相同sql语句
    SELECT * FROM x_test WHERE x_name = '1892008.205824857823401.800099203178258.8904820949682635656.62526521254';查询时间:0.014s ( 首次执行无缓存状态下 )

补充:使用前缀索引的执行过程

  1. 从index2的索引树上,找到满足索引值是“zhangs”的记录,找到第一个是ID1;
  2. 到主键索引树上查到ID1这一行,判断email的值满不满足where后的条件,不满足这一行丢弃。
  3. 继续回到index2这个索引树上查下一条记录,发现如果还是"zhangs",取出ID2,再回到ID2索引树上进行判断,如果值正确,将结果返回结果集中。
  4. 重复执行以上流程,直到从index2索引树上取出的数据不是“zhangs”,循环结束。

通过以上执行流程的分析你就可以知道,前缀索引会导致扫描的行数变多,这和你所指定前缀的长度有关。或许email(7)中的区分度就比email(6)高,就不会扫描那么多行。

也即是说使用前缀索引,定义好长度,就可以节省空间又不用额外增加太多的查询成本

那怎样定义前缀索引长度比较好呢?

实际上,建立索引时关注的是区分度,区分度越高,越能体现索引的价值和他的优势。因此我们可以通过统计索引上有不同的值来判断要使用多长的前缀。

select count(distinct email) as L from User;

MySQL 5.7 参考手册 - 前缀索引

总结

到此这篇关于MySQL前缀索引的文章就介绍到这了,更多相关MySQL前缀索引内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
MySQL基础(二)
Apr 05 MySQL
浅谈mysql执行过程以及顺序
May 12 MySQL
修改MySQL的默认密码的四种小方法
May 26 MySQL
MySQL为id选择合适的数据类型
Jun 07 MySQL
MySQL修炼之联结与集合浅析
Oct 05 MySQL
MySQL中int (10) 和 int (11) 的区别
Jan 22 MySQL
MySQL优化常用的19种有效方法(推荐!)
Mar 17 MySQL
一条 SQL 语句执行过程
Mar 17 MySQL
MySQL如何快速创建800w条测试数据表
Mar 17 MySQL
pt-archiver 主键自增
Apr 26 MySQL
MySQL实现字段分割一行转多行的示例代码
Jul 07 MySQL
MySQL一劳永逸永久支持输入中文的方法实例
Aug 05 MySQL
为什么MySQL不建议使用SELECT *
详解MySQL的主键查询为什么这么快
MySQL表锁、行锁、排它锁及共享锁的使用详解
navicat 连接Ubuntu虚拟机的mysql的操作方法
MySQL中IO问题的深入分析与优化
mysql的Buffer Pool存储及原理
一次Mysql update sql不当引起的生产故障记录
You might like
超外差式晶体管收音机的组装与统调
2021/03/01 无线电
实现树状结构的两种方法
2006/10/09 PHP
php xml文件操作实现代码(二)
2009/03/20 PHP
Drupal7中常用的数据库操作实例
2014/03/02 PHP
PHP获取某个月最大天数(最后一天)的方法
2015/07/29 PHP
8个超棒的学习 jQuery 的网站 推荐收藏
2011/04/02 Javascript
js制作的鼠标悬浮时产生的下拉框效果
2012/10/27 Javascript
原始XMLHttpRequest方法详情回顾
2013/11/28 Javascript
IE6下拉框图层问题探讨及解决
2014/01/03 Javascript
javascript实现避免页面按钮重复提交
2015/01/08 Javascript
js为什么不能正确处理小数运算?
2015/12/29 Javascript
javascript正则表达式之分组概念与用法实例
2016/06/16 Javascript
javaScript中定义类或对象的五种方式总结
2016/12/04 Javascript
正则验证小数点后面只能有两位数的方法
2017/02/28 Javascript
vue指令以及dom操作详解
2017/03/04 Javascript
jQuery插件FusionWidgets实现的Cylinder图效果示例【附demo源码】
2017/03/23 jQuery
原生JS改变透明度实现轮播效果
2017/03/24 Javascript
nodejs和C语言插入mysql数据库乱码问题的解决方法
2017/04/14 NodeJs
iscroll.js滚动加载实例详解
2017/07/18 Javascript
Bootstrap table使用方法汇总
2017/11/17 Javascript
微信小程序dom操作的替代思路实例分析
2018/12/06 Javascript
详解如何用webpack4从零开始构建react开发环境
2019/01/27 Javascript
Javascript实现打鼓效果
2021/01/29 Javascript
Python中运算符&quot;==&quot;和&quot;is&quot;的详解
2016/10/08 Python
浅谈PYTHON 关于文件的操作
2019/03/19 Python
python sorted方法和列表使用解析
2019/11/18 Python
浅析matlab中imadjust函数
2020/02/27 Python
pytorch中 gpu与gpu、gpu与cpu 在load时相互转化操作
2020/05/25 Python
详解python3 GUI刷屏器(附源码)
2021/02/18 Python
利用HTML5中Geolocation获取地理位置调用Google Map API在Google Map上定位
2013/01/23 HTML / CSS
使用canvas绘制贝塞尔曲线
2014/12/17 HTML / CSS
百联网上商城:i百联
2017/01/28 全球购物
大学毕业生简单自荐信
2013/11/05 职场文书
公司财务部岗位职责
2015/04/14 职场文书
浅谈Nginx 中的两种限流方式
2021/03/31 Servers
Django框架模板用法详解
2022/06/10 Python