mysql前缀索引 默认长度_如何确定前缀索引的长度?

mysql前缀索引 默认长度_如何确定前缀索引的长度?为什么需要前缀索引问题我们在对一张表里的某个字段或者多个字段建立索引的时候,是否遇到过这个问题。Specifiedkey’uniq_code’wastoolong;maxkeylengthis767bytes.表结构如下:createtable`t_account`(`id`BIGINT(20)UNSIGNEDNOTNULLauto_incrementCOMM…

大家好,又见面了,我是你们的朋友全栈君。

为什么需要前缀索引

问题

我们在对一张表里的某个字段或者多个字段建立索引的时候,是否遇到过这个问题。

Specified key ‘uniq_code’ was too long; max key length is 767 bytes.

表结构如下:

create table `t_account`(

`id` BIGINT(20) UNSIGNED NOT NULL auto_increment COMMENT ‘自增ID’,

`date` varchar(50) NOT NULL DEFAULT ” COMMENT ‘日期’,

`nick_name` varchar(50) NOT NULL DEFAULT ” COMMENT ‘昵称’,

`account` varchar(50) NOT NULL DEFAULT ” COMMENT ‘账号’,

`city` varchar(100) NOT NULL DEFAULT ” COMMENT ‘城市’,

PRIMARY KEY (`id`),

UNIQUE KEY `uniq_code` (`nick_name`,`account`,`city`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=’Test’;

复制代码

原因

在MySQL5.6里默认 innodb_large_prefix=0 限制单列索引长度不能超过767bytes。

在MySQL5.7里默认 innodb_large_prefix=1 解除了767bytes长度限制,但是单列索引长度最大还是不能超过3072bytes。

至于为什么是767字节,是依赖于具体的存储引擎实现的,找了官方文档,也没说为啥。 https://dev.mysql.com/doc/refman/8.0/en/create-index.html

varchar(n)占用几个字节跟字符集有关系:

字符类型若为gbk,每个字符占用2个字节,

字符类型若为utf8,每个字符最多占用3个字节,

字符类型若为utf8mb4,每个字符最多占用4个字节

复制代码

这里我设置的编码为utf8mb4编码,一个字符是占了4个字节,而我创建的索引50+50+100=200字符,总共就是800字节,所以超出了长度。

所以我们经常会见到把字段设置成varchar(255)长度的,在utf8字符集下这个是最大不超过767bytes的长度了,但是并不是一定要设置成varchar(255),还是要根据业务设置每个字段的长度,太长了也不利于我们建立联合索引。

解决办法

可以直接去改字段的长度,或者说,把索引的字段取消掉一些,但是这样改对表本身是不友好的。

通过限定字段的前n个字符为索引,可以通过衡量实际的业务中数据中的长度来取具体的值。

UNIQUE KEY `uniq_code` (`nick_name`(20),`account`(20),`city`(20))

复制代码

表示三个字段取前20字符作为唯一索引,这样的话就是长度就不会超出,这个就是我们说的前缀索引

修改单个索引的最大长度

修改索引限制长度需要在my.ini配置文件中添加以下内容,并重启:

#修改单列索引字节长度为767的限制,单列索引的长度变为3072

innodb_large_prefix=1

但是开启该参数后还需要开启表的动态存储或压缩:

系统变量innodb_file_format为Barracuda

ROW_FORMAT为DYNAMIC或COMPRESSED

复制代码

如何确定前缀索引的长度

上面我们说到可以通过前缀索引来解决索引长度超出限制的问题,但是我们改如何确定索引字段取多长的前缀才合适呢?

这里我们可以通过计算选择性来确定前缀索引的选择性,计算方法如下

全列选择性:

SELECT COUNT(DISTINCT column_name) / COUNT(*) FROM table_name;

某一长度前缀的选择性:

SELECT COUNT(DISTINCT LEFT(column_name, prefix_length)) / COUNT(*) FROM table_name;

当前缀的选择性越接近全列选择性的时候,索引效果越好。

前缀索引的优缺点

占用空间小且快

无法使用前缀索引做 ORDER BY 和 GROUP BY

无法使用前缀索引做覆盖扫描

有可能增加扫描行数

比如身份证加索引,可以加哈希索引或者倒序存储后加前缀索引。

再谈联合索引的创建

当我们不确定在一张表上建立的联合索引应该以哪个字段作为第一列时,上面的创建规则同样适用。

下面这个例子就是在建立customer_id,staff_id的联合索引时进行判断,最终选择(customer_id,staff_id)这样的组合。

# staff_id_selectivity: 0.0001

# customer_id_selectivity: 0.0373

# COUNT(*): 16049

# 通过结果发现,customer_id 的选择性更高,所以应该选择 customer_id 作为联合索引的第一列

SELECT

COUNT(DISTINCT staff_id)/COUNT(*) as staff_id_selectivity,

COUNT(DISTINCT customer_id)/COUNT(*) as customer_id_selectivity,

COUNT(*)

FROM payment

复制代码

所以说

当索引选择性越接近全列选择性的时候,索引效果越好。

也就是用此字段创建索引时,它在这个表的数据里区分度更加明显。

参考

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143845.html原文链接:https://javaforall.net

(0)
上一篇 2022年5月20日 下午6:40
下一篇 2022年5月20日 下午6:40


相关推荐

  • pycharm 激活成功教程

    pycharm 激活成功教程linux https blog csdn net u0 article details 找到了 pycharm 激活成功教程方法 激活成功教程码 licenseId 69 licenseeName ilanyu assigneeName assigneeEmai licenseRe

    2026年3月27日
    2
  • java异或运算符号_java异或运算符使用场景

    java异或运算符号_java异或运算符使用场景异或运算符“^”是异或运算符,异或的规则是转换成二进制比较,相同为0,不同为1.异或运算符可认为是无进位的二进制相加,如:6^7如6二进制为:00000110如7二进制为:00000111则6^7=1异或运算符性质(1)0^N=N;N^N=0(2)满足交换律及结合律简单的算法题(1)如果一个数组中只有一个数出现了奇数次,剩下的数都出现了偶数次,求这个出现了奇数次的数。publicstaticvoidgetData(int[]arr){int

    2022年10月5日
    4
  • 哈夫曼树 C语言实现

    哈夫曼树 C语言实现1 基本概念 a 路径和路径长度若在一棵树中存在着一个结点序列 k1 k2 kj 使得 ki 是 ki 1 的双亲 1 从 k1 到 kj 所经过的分支数称为这两点之间的路径长度 它等于路径上的结点数减 1 b 结点的权和带权路径长度在许多应用中 常常将树中的结点赋予一个有着某种意义的实数 我们称此实数为该结点的权 如下面一个树中的蓝色数字表示结点

    2025年10月26日
    6
  • TextMate 激活成功教程

    TextMate 激活成功教程网上google来两个方法,如下:(目的还只是个人学习只用,如果今后用于商业目的,一定支持正版)方法1:关于TextMate的注册这个号称TheMissingEditorfor Mac OSX的编辑器我就不介绍了,我就说说如何注册吧。第一种方法:花39欧元第二种方法:UninstallfirstandInstalagain,justopenthe TextMate unix

    2022年7月13日
    17
  • springcloud的feign原理_SpringMVC运行原理

    springcloud的feign原理_SpringMVC运行原理目录1.什么是Feign?2.OpenFeignvsSpringCloudFeign2.1.OpenFeign2.2.SpringCloudOpenFeign3.SpringCloudFeign的使用4.SpringCloudFeign的源码解析1.什么是Feign?Feign的初衷是:feignmakeswritingjava…

    2022年10月5日
    4
  • 【解决方案】无法将grub-efi-amd64-signed软件包安装到/target/【安装Ubuntu】

    【解决方案】无法将grub-efi-amd64-signed软件包安装到/target/【安装Ubuntu】简述很神秘 之前安装双系统的时候都是正常的 但是这次居然失败了 而且这个问题也很奇怪 文章目录简述电脑配置解决 GRUB2 安装失败的问题正确的操作是提要打开命令行输入下面的这些命令找到 Dash 测试电脑配置 Dell 不太知道主板是什么 但是通过开机时候按 F12 进入 BIOS mode 模式设置为 UEFI Securityoff 在 BIOS 上的操作进入到 SETUP 似乎是

    2026年3月17日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号