高性能的MySQL(4)Schema设计

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介:

一、设计中的陷阱

1、太多的列

MySQL的存储引擎API工作时需要在服务器层和存储引擎层之间通过行缓冲格式拷贝数据,然后在服务器层将缓冲内容解码为各个列。这是一个代价很高的操作,转换的代价依赖于列的数量,列太多的话,转换代价就会很高。

2、太多的关联

一个粗略的经验法则,如果希望查询和并发行好,单个查询不要超过10个表的关联。
3、过度的枚举

修改一个枚举列的值时,需要alter table的阻塞操作,代价很高。

4、避免不可能的值

1
2
CREATE  TABLE  date_test(
     dt DATETIME  NOT  NULL  DEFAULT  '0000-00-00 00:00:00' );

二、混用范式和反范式

最常见的反范式数据的方法是复制或者缓存,在不同的表中存储相同的特定列。缓存衍生值,比方说某个帖子的评论总数。混用的目的是在关联查询和增删改操作上做一个性能的折中考虑。

三、缓存表和汇总表

缓存表来存储那些某个主表上的一部分列数据,用来提供高效的查询操作。

汇总表保存的是使用GROUP BY语句聚合数据的表。

建立这些表是为了减少在主表上因为某些查询需要加很多特殊的索引。

当重建汇总表或缓存表时,通常需要保证数据在操作时仍然可用。这就需要通过使用“影子表”。

1
2
3
4
drop  table  if exists my_summary_new,my_summary_old;
create  table  my_summary_new  like  my_summay;
#导入数据
rename  table  my_summary  to  my_summary_old,my_summary_new  to  my_summary;

四、计数器

如果在表中保存计数器,在更新计数器时可能碰到并发问题,所以创建一张独立的表存储计数器通常是个好主意。

假设有一个计数器表,只有一行数据,记录网站的点击次数

143418684.png

网站的每次点击都会导致对计数器更新

1
update  hit_counter  set  cnt = cnt + 1;

问题在于,对于任何想要更新这一行的事务来说,这条记录会有全局的写锁,这会使事务只能串行执行。要获得更高的并发行,可以将计数器保存在多行中,每次随机选择一个行更新。

1
2
3
4
create  table  hit_counter(
     id tinyint unsigned  not  null  primary  key ,
     cnt  int  unsigned  not  null
) engine = innodb;

然后预先增加100行数据,当更新的时候随机选择一条记录来更新

1
update  hit_counter  set  cnt=cnt+1  where  id= rand()*100;

这样的统计结果就变成了

1
select  sum (cnt)  from  hit_counter;

一个常见的需求是每隔一段时间开始一个新的计数器,这个时候需要简单的修改一下表的设计

145314413.png

在这个场景中,不需要预先生成行,而用on duplicate key update 代替

1
insert  into  daily_hit_counter( day ,id,cnt)  values ( current_date (),rand() * 100,1)  on  duplicate  key  update  cnt = cnt + 1;

如果希望减少表的行数,以免表太大,可以写一个周期执行的任务,合并所有结果到一行,并删除其他所有的行。

151256420.png

五、加快ALTER TABLE速度

alter table 对大表来说是个问题。MySQL执行大部分修改表结果操作的方法是用新的结果创建一个空表,从旧表查出所有数据插入新表,然后删除旧表,这样的操作花费时间很长。

为了防止阻塞,有2个技巧

1、在一台不提供服务的机器上执行alter table,然后和提供服务的主库进行切换

2、影子拷贝

但并不是所有的alter table操作会引起表的重建,比方说修改或删除一个列的默认值。

一个很慢的方法是

1
alter  table  film  modify  column  sss tinyint(3)  not  null  default  5;

show status显示表重建了。

列的默认值存储在.frm文件中,所以只需要修改.frm文件,但是modify column都将导致表重建。

另一种快速方法,只修改.frm文件,所以很快。

1
alter  table  film  alter  column  sss  set  default  5;

六、快速创建MYISAM索引

为了高效的载入数据到myisam表中,可以先禁用索引,载入数据,然后重新启用索引。


1
2
3
alter  table  test disable keys;
# load  data
alter  table  test enable keys;

但是只针对非唯一索引,唯一索引还是会检测。
























本文转自shayang8851CTO博客,原文链接:http://blog.51cto.com/janephp/1309213,如需转载请自行联系原作者

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5月前
|
Kubernetes 关系型数据库 MySQL
高性能 MySQL 第四版(GPT 重译)(四)(4)
高性能 MySQL 第四版(GPT 重译)(四)
56 6
|
5月前
|
存储 算法 关系型数据库
高性能 MySQL 第四版(GPT 重译)(四)(1)
高性能 MySQL 第四版(GPT 重译)(四)
82 6
|
5月前
|
存储 运维 关系型数据库
高性能 MySQL 第四版(GPT 重译)(四)(2)
高性能 MySQL 第四版(GPT 重译)(四)
111 4
|
5月前
|
SQL 监控 关系型数据库
高性能 MySQL 第四版(GPT 重译)(三)(3)
高性能 MySQL 第四版(GPT 重译)(三)
86 4
|
5月前
|
存储 缓存 关系型数据库
高性能 MySQL 第四版(GPT 重译)(三)(1)
高性能 MySQL 第四版(GPT 重译)(三)
125 4
|
5月前
|
存储 关系型数据库 MySQL
高性能 MySQL 第四版(GPT 重译)(二)(4)
高性能 MySQL 第四版(GPT 重译)(二)
26 4
|
5月前
|
存储 关系型数据库 MySQL
高性能 MySQL 第四版(GPT 重译)(四)(3)
高性能 MySQL 第四版(GPT 重译)(四)
70 3
|
5月前
|
存储 关系型数据库 MySQL
高性能 MySQL 第四版(GPT 重译)(二)(3)
高性能 MySQL 第四版(GPT 重译)(二)
71 1
|
5月前
|
存储 缓存 JSON
高性能 MySQL 第四版(GPT 重译)(二)(2)
高性能 MySQL 第四版(GPT 重译)(二)
90 1
|
5月前
|
缓存 关系型数据库 MySQL
高性能 MySQL 第四版(GPT 重译)(二)(1)
高性能 MySQL 第四版(GPT 重译)(二)
139 1

热门文章

最新文章