MySQL 隔离数据列和前缀索引的使用总结


Posted in MySQL onMay 14, 2021

隔离数据列

通常,我们会发现查询语句会妨碍MySQL使用索引。除非在查询语句中列是独立的,否则MySQL不会使用这些列的索引。“隔离”的意思是索引列不应该成为表达式的一部分或者在一个查询函数体中。例如下面的例子就不会命中actor_id这个索引。

SELECT `actor_id` FROM `actor` WHERE `actor_id` + 1 = 2;

对于人来说,很容易知道查询条件实际是actor_id = 4,但是MySQL不会这么处理,因此养成简化WHERE判决条件的习惯,这意味着索引列独立地在比较操作符的一侧。下面是另外一个普遍错误的案例:

SELECT ... WHERE TO_DAYS(CURRENT_DATE) - TO_DAYS(date_col) <= 10;

前缀索引和索引的选择性

有时候需要在很长字符的列上建立索引,但这样会导致索引占据的空间很大且查询变慢。一个策略是使用哈希索引模拟,但有时候这未必是足够好,这个时候该怎么做?

通常是可以将索引列前面的部分字符建立索引来替换全字段索引提高性能和节省空间。但这种方式会使得选择性变差。索引的选择性是指独立的索引值筛选出的数据占整个数据集合的比例。高选择性的索引可以让MySQL过滤掉更多无关的数据。例如,一个唯一索引的选择性是1。 列的前缀通常在选择性方面已经能够提供足够好的性能。如果使用BLOB或TEXT或非常长的VARCHAR字段列,你必须定义前缀索引,以为MySQL不允许做全长度索引。

你需要在使用更长的前缀以获得更好的选择性和足够短的前缀以节省存储空间之间平衡。为了确定一个合适的前缀长度,查找出最高频的值,然后和最频繁的前缀进行比较。例如以城市数据表为例,我们可以使用如下的语句统计:

SELECT COUNT(*) as cnt, `name` FROM `common_city` GROUP BY `name` ORDER BY cnt DESC LIMIT 10

MySQL 隔离数据列和前缀索引的使用总结

可以看到这些城市名称出现的次数比较多。现在我们可以使用1个字的前缀查找最为频繁的城市名称前缀。

SELECT COUNT(*) as cnt, LEFT(`name`, 1) as pref FROM `common_city` GROUP BY pref ORDER BY cnt DESC LIMIT 10

MySQL 隔离数据列和前缀索引的使用总结

可以看到1个字找出来的数据集更多了,这会导致独立选中的机会越少,因此需要调整一下前缀的长度。例如调到3个字。

SELECT COUNT(*) as cnt, LEFT(`name`, 3) as pref FROM `common_city` GROUP BY pref ORDER BY cnt DESC LIMIT 10

MySQL 隔离数据列和前缀索引的使用总结

可以看到这和全长度的相差不多,那实际三个字的前缀就够了(原文使用的是英文城市数据表,字符会更多)。另外一种方式是使用不同长度的前缀数量与全字段数量的比例评估多少合适。例如:

SELECT 
  COUNT(DISTINCT LEFT(`name`, 1)) / COUNT(`name`) as pref1, 
  COUNT(DISTINCT LEFT(`name`, 2)) / COUNT(`name`) as pref2, 
  COUNT(DISTINCT LEFT(`name`, 3)) / COUNT(`name`) as pref3, 
  COUNT(DISTINCT LEFT(`name`, 4)) / COUNT(`name`) as pref4 
FROM `common_city`

MySQL 隔离数据列和前缀索引的使用总结

数值越接近于1效果越好,但是也可以看到,随着前缀长度的加长改善的空间越小。只看平均值并不是一个好主意,还需要检查一下最坏情况。也许会觉得3-4个字足够了,但是如果数据分布很不均匀,那可能会存在陷阱。因此还需要检查一下前缀少的是不是存在一个前缀对应的数据与其他相比极其多的情况。最后可以给指定的列加前缀索引。

ALTER TABLE `common_city` ADD KEY (name(3));

前缀索引在节省空间和提高效率方面表现不错,但是也有缺陷,那就是在ORDER BY和GROUP BY上无法使用索引(实际验证在MySQL 5.7以上版本也有用)。另外一种常见的场景是在较长的十六进制字符串中,例如存储的sessionId,取前8位前缀做索引将过滤很多无关数据,效果很好。

以上就是MySQL 隔离数据列和前缀索引的使用总结的详细内容,更多关于MySQL 隔离数据列和前缀索引的资料请关注三水点靠木其它相关文章!

MySQL 相关文章推荐
详解MySQL 用户权限管理
Apr 20 MySQL
MySQL5.7并行复制原理及实现
Jun 03 MySQL
MySQL为id选择合适的数据类型
Jun 07 MySQL
Mysql案例刨析事务隔离级别
Sep 25 MySQL
MySQL和Oracle批量插入SQL的通用写法示例
Nov 17 MySQL
mysql分组后合并显示一个字段的多条数据方式
Jan 22 MySQL
MySQL中B树索引和B+树索引的区别详解
Mar 03 MySQL
MySQL中一条update语句是如何执行的
Mar 16 MySQL
分享MySQL常用 内核 Debug 几种常见方法
Mar 17 MySQL
分析MySQL优化 index merge 后引起的死锁
Apr 19 MySQL
MySQL的prepare使用以及遇到的bug
May 11 MySQL
深入理解MySQL中MVCC与BufferPool缓存机制
May 25 MySQL
MySQL 使用自定义变量进行查询优化
May 14 #MySQL
MySQL 逻辑备份与恢复测试的相关总结
May 14 #MySQL
MySQL 可扩展设计的基本原则
May 14 #MySQL
MySQL主从搭建(多主一从)的实现思路与步骤
May 13 #MySQL
MySQL如何构建数据表索引
May 13 #MySQL
MySQL 自定义变量的概念及特点
May 13 #MySQL
为什么mysql字段要使用NOT NULL
You might like
php基础知识:类与对象(5) static
2006/12/13 PHP
台湾中原大学php教程孙仲岳主讲
2008/01/07 PHP
基于magic_quotes_gpc与magic_quotes_runtime的区别与使用介绍
2013/04/22 PHP
php.ini save_handler 修改不生效的解决办法
2014/07/22 PHP
利用PHP内置SERVER开启web服务(本地开发使用)
2020/01/22 PHP
javascript 显示当前系统时间代码
2009/12/28 Javascript
动态载入/删除/更新外部 JavaScript/Css 文件的代码
2010/07/03 Javascript
关于window.pageYOffset和document.documentElement.scrollTop
2011/04/05 Javascript
利用json获取字符出现次数的代码
2012/03/22 Javascript
javascript实现tabs选项卡切换效果(扩展版)
2013/03/19 Javascript
html+css+js实现xp window界面及有关功能
2013/03/26 Javascript
javascript实现无缝上下滚动特效
2015/12/16 Javascript
详解JavaScript中双等号引起的隐性类型转换
2016/05/30 Javascript
ThinkJS中如何使用MongoDB的CURD操作
2016/12/13 Javascript
微信页面倒计时代码(解决safari不兼容date的问题)
2016/12/13 Javascript
微信小程序之GET请求的实例详解
2017/09/29 Javascript
JS端基于download.js实现图片、视频时直接下载而不是打开预览
2020/05/09 Javascript
jquery实现穿梭框功能
2021/01/19 jQuery
python逐行读取文件内容的三种方法
2014/01/20 Python
python tensorflow学习之识别单张图片的实现的示例
2018/02/09 Python
手把手教你如何安装Pycharm(详细图文教程)
2018/11/28 Python
python 使用matplotlib 实现从文件中读取x,y坐标的可视化方法
2019/07/04 Python
Django实现跨域的2种方法
2019/07/31 Python
利用python中的matplotlib打印混淆矩阵实例
2020/06/16 Python
俄罗斯有趣和原创礼物网上商店:MagicMag
2019/08/01 全球购物
什么是事务?事务有哪些性质?
2012/03/11 面试题
企业面试题试卷附带答案
2015/12/20 面试题
优良学风班申请材料
2014/02/13 职场文书
关心下一代工作先进事迹
2014/08/15 职场文书
学校总务处领导班子民主生活会对照检查材料思想汇报
2014/09/27 职场文书
2014年检验员工作总结
2014/11/19 职场文书
奥巴马开学演讲观后感
2015/06/12 职场文书
外出培训学习心得体会
2016/01/18 职场文书
《我们的民族小学》教学反思
2016/02/19 职场文书
导游词创作书写原则以及开场白技巧怎么学?
2019/09/25 职场文书
导游词之贵州百里杜鹃
2019/10/29 职场文书