《MYSQL实战45讲》笔记(11-20)
创始人
2024-05-10 16:25:02
0

11:怎么给字符串字段加索引?

业务场景:基于字符串字段做查询。例如邮箱登录等等。

前缀索引的优势:相对于整个字段索引,前缀索引的占用空间更小。
前缀索引带来的问题:区分度过低的时候会额外扫描次数。

使用前缀索引需要定义好长度,就可以节省空间又不用额外增加太多查询成本。

区分度语句:

select
count(distinct left(field,4))as L4,
count(distinct left(field,5))as L5,
count(distinct left(field,6))as L6,
count(distinct left(field,7))as L7,
from table;

使用前缀索引 = 去掉索引覆盖,因为无法确定前缀索引是否覆盖全部内容。

其他问题:例如身份证字段前6位区分不够好,加到12个字段又会导致过大,页存放数据变少,查询效率变低。

  • 倒序存储:将身份证号倒过来存,身份证码后六位提供足够的区分度。
  • hash字段:插入身份证号时通过crc32函数得到一个校验码,为这个字段设置索引,同时在判断的时候比较身份证号,这样索引长度就变为4个字节。
alter table t add id_card_crc int unsigned, add index(id_card_crc);

相同点:不支持范围查询,

小总结:

  • 直接创建完整索引,这样可能比较占用空间;
  • 创建前缀索引,节省空间,但会增加查询扫描次数,并且不能使用覆盖索引;
  • 倒序存储,再创建前缀索引,用于绕过字符串本身前缀的区分度不够的问题;
  • 创建hash字段索引,查询性能稳定,有额外的存储和计算消耗,跟第三种方式一样,都不支持范围扫描。

思考题

维护一个学校的学生信息数据库,学生登录名的统一格式是”学号@gmail.com", 而学号的规则是:十五位的数字,其中前三位是所在城市编号、第四到第六位是学校编号、第七位到第十位是入学年份、最后五位是顺序编号。

系统登录的时候都需要学生输入登录名和密码,验证正确后才能继续使用系统。就只考虑登录验证这个行为的话,你会怎么设计这个登录名的索引呢?

我的回答:学号只有后五位是区分度,根据所学,使用第三种倒序存储。
标准答案:而其实在此基础上,可以用数字类型来存这9位数字。比如201100001,这样只需要占4个字节。其实这个就是一种hash,只是它用了最简单的转换规则:字符串转数字的规则,而刚好我们设定的这个背景,可以保证这个转换后结果的唯一性

12:为什么我的MySQL会“抖”一下?

场景:一条SQL语句,正常执行的时候特别快,但是有时也不知道怎么回事,它就会变得特别慢,并且这样的场景很难复现,它不只随机,而且持续时间还很短。

脏页

13:为什么表数据删掉一半,表文件大小不变?

参数 innodb_file_per_table

innodb_file_per_table
show VARIABLES where Variable_name = 'innodb_file_per_table'

在这里插入图片描述

我建议你不论使用MySQL的哪个版本,都将这个值设置为ON。

14:count(*)这么慢,我该怎么办?

show table status

15: 答疑文章(一):日志和索引相关问题

16:“order by”是怎么工作的?

MySQL会给每个线程分配一块内存用于排序,称为sort_buffer。

show VARIABLES where Variable_name = 'sort_buffer_size'

在这里插入图片描述

17: 如何正确地显示随机消息?

对于对 InnoDB I 表来说 表 ,执行全字段排序会减少磁盘访问,因此会被优先选择。

18:为什么这些SQL语句逻辑相同,性能却差异巨大?

19:为什么我只查一行的语句,也执行这么慢?

20:幻读是什么,幻读有什么问题?

建表语句

CREATE TABLE `t_2001` (`id` INT ( 11 ) NOT NULL,`c` INT ( 11 ) DEFAULT NULL,`d` INT ( 11 ) DEFAULT NULL,PRIMARY KEY ( `id` ),KEY `c` ( `c` ) 
) ENGINE = INNODB;

数据

insert into t_2001 values(0,0,0),(5,5,5),(10,10,10),(15,15,15),(20,20,20),(25,25,25);
BEGIN;SELECT* FROMt_2001 WHEREd = 5 FOR UPDATE;
COMMIT;

这个语句会命中d=5的这一行,对应的主键id=5,因此在select 语句执行完成后,id=5这一行会加一个写锁,而且由于两阶段锁协议,这个写锁会在执行commit语句的时候释放。

由于字段d上没有索引,因此这条查询语句会做全表扫描。那么,其他被扫描到的,但是不满足条件的5行记录上,会不会被加锁呢?

幻读是什么?

一个假设的场景,实际运行B和C会阻塞。
在这里插入图片描述

幻读指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。

  • 在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的。因此,幻读在“当前读”下才会出现。(for update)

  • 上面session B的修改结果,被session A之后的select语句用“当前读”看到,不能称为幻读。幻读仅专指“新插入的行”。

幻读有什么问题?

语义:我要将 d=5的所有行锁住,实际上没有锁住。

select * from t_2001 where d= 5 for update 

一致性:

也就是说,即使把所有的记录都加上锁,还是阻止不了新插入的记录

如何解决幻读?

为了解决幻读问题,InnoDB只好引入新的锁,也就是间隙锁(Gap Lock),顾名思义,间隙锁,锁的就是两个值之间的空隙。比如文章开头的表t,初始化插入了6个记录,这就产生了7个间隙。

当你执行 select *fromt where d=5 for update的时候,就不止是给数据库中已有的6个记录加上了行锁,还同时加了7个间隙锁。这样就确保了无法再插入新的记录。

间隙锁和行锁合称next-key lock,每个next-key lock是前开后闭区间。

小结

相关内容

热门资讯

贵州天河潭风景区的导游词 贵州天河潭风景区的导游词  各位游客们,我是你们导游×××,本次旅行的目的地是贵州的天河潭景区。天河...
河南开封山陕甘会馆导游词 河南开封山陕甘会馆导游词范文  各位朋友大家好,欢迎您来到山陕甘会馆,大家一路上辛苦了,我是您这次行...
介绍公园的导游词 介绍公园的导游词范文  篇一:北滘公园导游词  欢迎您前往北考公园。  北郊镇新中心城区,东承德路西...
小学生导游词结束语 导语:导游词是导游人员引导游客观光游览时的讲解词,是导游员同游客交流思想,向游客传播文化知识的工具,...
个园导游词   个园导游词(一)  个园是扬州现存历史最悠久、保存最完好的盐商园林,南临中国十大历史文化名街东关...
千岛湖景点导游词 千岛湖景点导游词  作为一位杰出的导游,就有可能用到导游词,一篇完整的导游词,其结构一般包括习惯用语...
南京中山陵导游词 南京中山陵导游词(精选5篇)  导读:南京中山陵美不胜收,远远望去,一大面山,郁郁葱葱。下面是小编整...
烟台的海导游词 烟台的海导游词15篇  作为一名专门为游客提供帮助的导游,很有必要精心设计一份导游词,导游词具有极强...
天津市古文化街导游词 天津市古文化街导游词  来自××的朋友大家好!  首先我代表青年旅行社欢迎各...
杭州西湖中英文导游词 杭州西湖中英文导游词  杭州西湖的导游词怎么写?下面小编为大家推荐2篇中英文的范文,希望对大家有帮助...
西安秦始皇兵马俑博物馆导游词 西安秦始皇兵马俑博物馆导游词  一篇完整的导游词,其结构一般包括习惯用语、概括介绍、重点讲解三个部分...
杭州山沟沟概况导游词 杭州山沟沟概况导游词  作为一名默默奉献的导游,总归要编写导游词,导游词作为一种解说的文体,它的作用...
我是大连小导游作文共60篇 我是大连小导游作文 第一篇亲爱的朋友们,旅途辛苦了,欢迎来到我的家乡—福州永泰,我是今天的小导游,大...
呼和浩特大昭寺导游词 呼和浩特大昭寺导游词  大昭寺成为藏式宗教建筑的千古典范,是旅游的胜地,吸引了很多游客来参观,导游要...
逍遥津导游词 逍遥津导游词位于合肥市旧城的东北角,是一座约20万平方米的城市公园。逍遥津古为淝水上的一个津渡。公园...
导游词开场白 导游词开场白导游词开场白有一句广告词说:心随我动,沟通无限,那我与在座各位朋友的沟通就从我的自我介绍...
苏州盘门三景导游词 苏州盘门三景导游词范例  苏州历史文化名城遐迩闻名在于她的历史悠久、人文荟萃、风景优美。盘门景区位于...
游长城导游词 游长城导游词  长城是世界七大奇迹之一。它像一条巨龙盘踞在中国北方的辽阔的土地上。它是中国古代劳动人...
颐和园导游词400字 颐和园导游词400字  一、颐和园简介  颐和园,中国清朝时期皇家园林,前身为清漪园,坐落在北京西郊...
辽宁省五女山导游词 辽宁省五女山导游词  作为一名具备丰富知识的导游,时常需要用到导游词,导游词的主要特点是口语化,此外...