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 14 MySQL
mysql 8.0.24版本安装配置方法图文教程
May 12 MySQL
mysql数据库入门第一步之创建表
May 14 MySQL
Mysql官方性能测试工具mysqlslap的使用简介
May 21 MySQL
MySQL 数据类型选择原则
May 27 MySQL
MySql开发之自动同步表结构
May 28 MySQL
MySQL 百万级数据的4种查询优化方式
Jun 07 MySQL
MYSQL 表的全面总结
Nov 11 MySQL
Arthas排查Kubernetes中应用频繁挂掉重启异常
Feb 28 MySQL
MySQL之MyISAM存储引擎的非聚簇索引详解
Mar 03 MySQL
优化Mysql查询的示例
Apr 26 MySQL
mysql 子查询的使用
Apr 28 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
德生PL990,目前市面上唯一一款便携式插卡蓝牙全波段高性能收音机
2021/03/02 无线电
PHP 日期加减的类,很不错
2009/10/10 PHP
PHP防止注入攻击实例分析
2014/11/03 PHP
php中使用base HTTP验证的方法
2015/04/20 PHP
从刷票了解获得客户端IP的方法
2015/09/21 PHP
php redis实现文章发布系统(用户投票系统)
2017/03/04 PHP
网页和浏览器兼容性问题汇总(draft1)
2009/06/01 Javascript
传智播客学习之JavaScript基础篇
2009/11/13 Javascript
javascript操作Cookie(设置、读取、删除)方法详解
2015/03/18 Javascript
Bootstrap table分页问题汇总
2016/05/30 Javascript
基于d3.js实现实时刷新的折线图
2016/08/03 Javascript
JavaScript实现简单评论功能
2017/08/17 Javascript
利用js给datalist或select动态添加option选项的方法
2018/01/25 Javascript
如何实现双向绑定mvvm的原理实现
2019/05/28 Javascript
[05:43]VG.R战队教练Mikasa专访:为目标从未停止战斗
2016/08/02 DOTA
Python实现数据库并行读取和写入实例
2017/06/09 Python
Java与Python两大幸存者谁更胜一筹呢
2018/04/12 Python
Python实现ping指定IP的示例
2018/06/04 Python
Python实现正则表达式匹配任意的邮箱方法
2018/12/20 Python
解决python测试opencv时imread导致的错误问题
2019/01/26 Python
Pycharm编辑器功能之代码折叠效果的实现代码
2020/10/15 Python
Html5 语法与规则简要概述
2014/07/29 HTML / CSS
澳大利亚领先的皮肤诊所:Skin Matrix(抗衰老、痤疮专家、药妆护肤)
2018/05/20 全球购物
波兰在线杂货店:Polski Koszyk
2019/11/02 全球购物
Hurley官方网站:扎根于海滩生活方式的全球青年文化品牌
2020/05/18 全球购物
一家外企的面试题目(C/C++面试题,C语言面试题)
2014/03/24 面试题
国际商务专业职业生涯规划书范文
2014/01/17 职场文书
优秀少先队工作者事迹材料
2014/05/13 职场文书
关于诚信的活动方案
2014/08/18 职场文书
献爱心大型公益活动策划方案
2014/09/15 职场文书
小学少先队辅导员述职报告
2015/01/10 职场文书
党员廉洁自律个人总结
2015/02/13 职场文书
劳动保障个人工作总结
2015/03/04 职场文书
关爱空巢老人感想
2015/08/11 职场文书
大学学习委员竞选稿
2015/11/20 职场文书
Python中22个万用公式的小结
2021/07/21 Python