首页 > 数据库 > MySQL Explain执行计划key_len详解(特意针对date和datetime详细测试说明)

MySQL Explain执行计划key_len详解(特意针对date和datetime详细测试说明)

时间:2022-09-01 20:11:30浏览次数:50  
标签:varchar Explain len datetime key notnull test null

MySQL Explain执行计划key_len详解(特意针对date和datetime详细测试说明)

我们在使用Explain查看SQL执行计划时,其中有一列为key_ken

key_len表示使用的索引长度,那么key_len的长度是如何计算的? 对于复合索引,通过key_len可以看出sql使用了复合索引的哪几个字段。

常见的列类型长度计算:

列类型 是否为空 长度 key_len 备注
tinyint 允许Null 1 key_len = 1+1 允许NULL,key_len长度加1
tinyint 不允许Null 1 key_len = 1 不允许NULL
int 允许Null 4 key_len = 4+1 允许NULL,key_len长度加1
int not null 不允许Null 4 key_len = 4 不允许NULL
bigint 允许Null 8 key_len = 8+1 允许NULL,key_len长度加1
bigint not null 不允许Null 8 key_len = 8 不允许NULL
char(1) 允许Null utf8mb4=4,utf8=3,gbk=2 key_len = 1*3 + 1 允许NULL,字符集utf8,key_len长度加1
char(1) not null 不允许Null utf8mb4=4,utf8=3,gbk=2 key_len = 1*3 不允许NULL,字符集utf8
varchar(10) 允许Null utf8mb4=4,utf8=3,gbk=2 key_len = 10*3 + 2 + 1 动态列类型,key_len长度加2,允许NULL,key_len长度加1
varchar(10) not null 不允许Null utf8mb4=4,utf8=3,gbk=2 key_len = 10*3+ 2 动态列类型,key_len长度加2

其他:

  1. 所有的索引字段,如果设置允许null,key_len则需要加1。
  2. char和varchar型的字段长度,char和varchar是日常使用最多的字符类型。char(N)用于保存固定长度的字符串,长度最大为255,比指定长度大的值将被截短,而比指定长度小的值将会用空格进行填补。
    1. varchar(N)用于保存可以变长的字符串,长度最大为65535,只存储字符串实际实际需要的长度(它会增加一个额外字节来存储字符串本身的长度),varchar使用额外的1~2字节来存储值的的长度,如果列的最大长度小于或者等于255,则用1字节,否则用2字节。
    2. char和varchar跟字符编码也有密切的联系,latin1占用1个字节,gbk占用2个字节,utf8占用3个字节,utf8mb4占用4个。(不同字符编码占用的存储空间不同)
  3. 索引长度 char()和varchar()索引长度的计算公式:key_len=基础长度 * 列长度 + 1(如果是允许null) + 2(如果是变长列) (Character Set基础长度:utf8mb4=4,utf8=3,gbk=2,latin1=1)
  4. 浮点型: float key_len=4 ; double key_len=8

日期&时间类型的字段长度(根据版本有变化,单独说明)

DataType orage Required Before MySQL 5.6.4 (版本低于5.6.4 ) Required as of MySQL 5.6.4 (版本高于5.6.4 )
YEAR 1byte 1byte
DATE 3bytes 3bytes
TIME 3bytes 3 bytes + fractional seconds storage
DATETIME 8bytes 5 bytes + fractional seconds storage
TIMESTAMP 4bytes 4 bytes + fractional seconds storage

查看db版本信息 select version() from dual;

如果使用的是mariadb,可查看官网的说明,(1、MariaDB 10.1 发布时间2015 对应 MySQL 5.6 发布时间2013 2、MariaDB 10.2 发布时间2017 对应 MySQL 5.7 发布时间2015)

验证SQL


drop table if exists TM_TEST_KEY_LEN;
CREATE TABLE `TM_TEST_KEY_LEN` (
  `account_id` bigint(20)  NOT null ,
  `test_varchar_notnull` varchar(32) NOT null DEFAULT '',
  `test_varchar_null` varchar(32) DEFAULT null ,
  `test_char_notnull` char(32) NOT null DEFAULT '',
  `test_char_null` char(32) DEFAULT null ,
  `test_date_notnull` date NOT null ,
  `test_date_null` date DEFAULT null ,
  `test_datetime_notnull` datetime NOT null ,
  `test_datetime_null` datetime DEFAULT null ,
  PRIMARY KEY (`account_id`),
  KEY IDX_test_varchar_notnull(test_varchar_notnull),
  KEY IDX_test_varchar_null(test_varchar_null),
  KEY IDX_test_char_notnull(test_char_notnull),
  KEY IDX_test_char_null(test_char_null),
  KEY IDX_test_date_notnull(test_date_notnull),
  KEY IDX_test_date_null(test_date_null),
  KEY IDX_test_datetime_notnull(test_datetime_notnull),
  KEY IDX_test_datetime_null(test_datetime_null)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4;
-- 查看索引
show index from tm_test_key_len ;
-- 重新组织索引
analyze table tm_test_key_len;

-- 插入一条测试数据
INSERT INTO tm_test_key_len (account_id, test_varchar_notnull, test_varchar_null, test_char_notnull, test_char_null, test_date_notnull, test_date_null, test_datetime_notnull, test_datetime_null) 
VALUES(1, 'qq', 'qq', 'ww', 'ww', '2022-09-01', '2022-09-01', '2022-09-01', '2022-09-01');

-- 测试结果
# IDX_test_varchar_notnull 结果key_len=130 = 4*32+2
# IDX_test_varchar_null 结果key_len=131 = 4*32+2+1
# IDX_test_char_notnull 结果key_len=128 = 4*32
# IDX_test_char_null 结果key_len=129 = 4*32+1
# IDX_test_date_notnull 结果key_len=3 = 3
# IDX_test_date_null 结果key_len=4 = 3+1
# IDX_test_datetime_notnull 结果key_len=8= 8  -- 此处为8是因为我用MariaDb版本比较低,还是10.0.10版本 相当于MySQL5.6 最新版本MySQL中测试结果是5
# IDX_test_datetime_null 结果key_len=9= 8+1


explain
SELECT * from TM_TEST_KEY_LEN   where  test_datetime_null = '2022-09-01' ;  

标签:varchar,Explain,len,datetime,key,notnull,test,null
From: https://www.cnblogs.com/starmoon1994/p/16647697.html

相关文章

  • MySQL5.7 datetime设置默认为当前时间
    DROPTABLEIFEXISTS`strategy`;CREATETABLE`strategy`(`id`bigint(11)NOTNULLAUTO_INCREMENTCOMMENT'自增ID',`create_time`datetime(3)DEFAULTCURR......
  • 原aio系列文档(5)----t-io api思维导图,作者 talent-tan
    原aio系列文档(5)----t-ioapi思维导图   作者:talent-tan 摘要:t-io横空出世,但被人诟病最多的就是没有详细的api,花了3小时整理了一下,希望不负众望t......
  • 使用selenium自动化模块实现登录12306
    importtimefromselenium.webdriverimportChromefromselenium.webdriver.chrome.optionsimportOptionsfromselenium.webdriver.common.byimportByfromselenium.w......
  • Calendar类
    java.util.calendar 类是一个抽象类,它提供了与在某一特定时刻和一组日历字段如YEAR,MONTH,DAY_OF_MONTH,HOUR等,并为操作日历字段,如获取的日期转换方法下周。以下是关于日历的......
  • [Typescript Challenges] 1. Easy - Pick
    Forexample:interfaceTodo{title:stringdescription:stringcompleted:boolean}typeTodoPreview=MyPick<Todo,'title'|'completed'>consttodo:......
  • Selenium+Python微博爬虫实战
    读研后终日苦于写论文(zuoniuma),一年来也没时间更新微博,想想还是要在假期抽点时间,将一年所学记点笔记,或许日后还有些用处。惭愧的是这一年在快节奏的压迫下,很多知识没有......
  • 公共方法、len、del、max、min、range、enumerate
    1.len()#1.字符串str1='abvdse'print(len(str1))#6#2.列表list1=[10,20,30,40]print(len(list1))#4#3.元组t1=(10,50,60,20,80)print(......
  • 2022牛客多校第8场 I.Equivalence in Connectivity
    题目大意给定一张\(n\)个点\(m\)条边的无向图,定义两张图\(G_1\)和\(G_2\)连通性等价,当且仅当\(\forallu,v\inG_1\),只要在\(G_1\)中\(u\)和\(v\)连通,一定......
  • explain详解
    explain用法mysql中explain有两种用法,一种是explaintable_name用来查看表结构信息,另一种就是explainselect....用来查询sql执行计划,分析sql性能。查看表结构 查......
  • selenium 常用操作汇总
    使用selenium1、查看Chrome版本去下载浏览器驱动驱动下载链接2、selenium官方网站官方文档selenium通信原理对于每一条Selenium脚本,一个http请求会被......