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 相关文章推荐
低版本Druid连接池+MySQL驱动8.0导致线程阻塞、性能受限
Jul 01 MySQL
mysql连接查询中and与where的区别浅析
Jul 01 MySQL
MySQL Shell import_table数据导入的实现
Aug 07 MySQL
MySQL空间数据存储及函数
Sep 25 MySQL
mysql中int(3)和int(10)的数值范围是否相同
Oct 16 MySQL
利用JuiceFS使MySQL 备份验证性能提升 10 倍
Mar 17 MySQL
MySQL 数据库范式化设计理论
Apr 22 MySQL
讲解MySQL增删改操作
May 06 MySQL
mysql如何查询连续记录
May 11 MySQL
mysql字段为NULL索引是否会失效实例详解
May 30 MySQL
MySql中的json_extract函数处理json字段详情
Jun 05 MySQL
MySQL数据管理操作示例讲解
Dec 24 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在页面中调用fckeditor编辑器的方法
2011/06/10 PHP
简单谈谈PHP中strlen 函数
2016/02/27 PHP
Laravel中注册Facades的步骤详解
2016/03/16 PHP
php利用嵌套数组拼接与解析json的方法
2017/02/07 PHP
PHP开发api接口安全验证操作实例详解
2020/03/26 PHP
JQuery获取文本框中字符长度的代码
2011/09/29 Javascript
js检测输入内容全为空格的方法
2014/05/03 Javascript
JavaScript中的类与实例实现方法
2015/01/23 Javascript
深入理解JavaScript系列(34):设计模式之命令模式详解
2015/03/03 Javascript
swtich/if...else的替代语句
2015/08/16 Javascript
jQuery技巧之让任何组件都支持类似DOM的事件管理
2016/04/05 Javascript
判断JS对象是否拥有某属性的方法推荐
2016/05/12 Javascript
Angularjs在初始化未完毕时出现闪烁问题的解决方法分析
2016/08/05 Javascript
微信小程序 数据封装,参数传值等经验分享
2017/01/09 Javascript
jQuery实现大图轮播
2017/02/13 Javascript
详解打造 Vue.js 可复用组件
2017/03/24 Javascript
移动端Ionic App 资讯上下循环滚动的实现代码(跑马灯效果)
2017/08/29 Javascript
Angular实现下载安装包的功能代码分享
2017/09/05 Javascript
AngularJs用户登录问题处理(交互及验证、阻止FQ处理)
2017/10/26 Javascript
React Native 搭建开发环境的方法步骤
2017/10/30 Javascript
js点击时关闭该范围下拉菜单之外的菜单方法
2018/01/11 Javascript
JS 使用 window对象的print方法实现分页打印功能
2018/05/16 Javascript
Nuxt.js SSR与权限验证的实现
2018/11/21 Javascript
vue实现标签云效果的示例
2020/11/09 Javascript
Python基础练习之用户登录实现代码分享
2017/11/08 Python
python 爬虫网页登陆的简单实现
2020/11/30 Python
英国时尚高尔夫服装购物网站:Trendy Golf
2020/01/10 全球购物
日本化妆品植村秀俄罗斯官方网站:Shu Uemura俄罗斯
2020/02/01 全球购物
销售经理竞聘书
2014/03/31 职场文书
精神文明建设先进工作者事迹材料
2014/05/02 职场文书
2014年计生协会工作总结
2014/11/21 职场文书
清洁工个人工作总结
2015/03/05 职场文书
2015年护理工作总结范文
2015/04/03 职场文书
Python可视化学习之seaborn调色盘
2022/02/24 Python
MySQL的InnoDB存储引擎的数据页结构详解
2022/03/03 MySQL
永中文档在线转换预览基于nginx配置部署方案
2022/06/10 Servers