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

 更新时间:2021年05月14日 09:47:40   作者:岛上码农  
正确地创建和使用索引对于查询性能十分重要。由于存在很多种特殊场景的优化和行为,因此有很多种方式去有效选择和使用索引。因此,决定如何使用索引这一项技能是需要经验和时间的积累去培养的。以下会介绍一些如何有效使用索引的方法。

隔离数据列

通常,我们会发现查询语句会妨碍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

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

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

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

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

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

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`

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

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

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

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

相关文章

  • MySQL数据库的实时备份知识点详解

    MySQL数据库的实时备份知识点详解

    本篇文章给大家分享了关于MySQL数据库的实时备份知识点内容,有需要的朋友们可以参考下。
    2018-08-08
  • Mysql指定日期区间的提取方法

    Mysql指定日期区间的提取方法

    这篇文章主要介绍了Mysql指定日期区间的提取方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-07-07
  • MySQL默认sql_mode浅析

    MySQL默认sql_mode浅析

    这篇文章主要为大家介绍了MySQL默认sql_mode浅析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • 浅谈mysql的timestamp存在的时区问题

    浅谈mysql的timestamp存在的时区问题

    本文主要介绍了浅谈mysql的timestamp存在的时区问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • mysql 5.7.18 安装配置方法图文教程(CentOS7)

    mysql 5.7.18 安装配置方法图文教程(CentOS7)

    这篇文章主要为大家详细介绍了CentOS 7下mysql 5.7.18 安装配置方法图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • MySQL 查询速度慢与性能差的原因与解决方法

    MySQL 查询速度慢与性能差的原因与解决方法

    随着网站数据量与访问量的增加,MySQL 查询速度慢与性能差的问题就日渐明显,这里为大家分享一下解决方法,需要的朋友可以参考下
    2019-09-09
  • MySQL如何构建数据表索引

    MySQL如何构建数据表索引

    索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信息。本文将通过一个案例带领你理解索引的概念
    2021-05-05
  • Mysql中的join操作

    Mysql中的join操作

    这篇文章主要介绍了Mysql join操作的相关资料,需要的朋友可以参考下
    2017-05-05
  • Linux下安装MySQL教程

    Linux下安装MySQL教程

    上一篇文章详细介绍windows下MySQL安装教程,这篇就从最基本的安装MySQL-Linux环境开始,文章为绕MySQL安装展开内容,需要的朋友可以参考一下
    2021-11-11
  • Mysql时间轴数据 获取同一天数据的前三条

    Mysql时间轴数据 获取同一天数据的前三条

    这篇文章主要介绍了Mysql时间轴数据 获取同一天数据的前三条 ,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07

最新评论