首页 > 数据库 >MySQL进阶实战6,缓存表、视图、计数器表

MySQL进阶实战6,缓存表、视图、计数器表

时间:2022-11-27 23:00:21浏览次数:60  
标签:汇总表 缓存 进阶 视图 查询 num MySQL

一、缓存表和汇总表

有时提升性能最好的方法是在同一张表中保存衍生的冗余数据,有时候还需要创建一张完全独立的汇总表或缓存表。

  • 缓存表用来存储那些获取很简单,但速度较慢的数据;
  • 汇总表用来保存使用group by语句聚合查询的数据;

对于缓存表,如果主表使用InnoDB,用MyISAM作为缓存表的引擎将会得到更小的索引占用空间,并且可以做全文检索。

在使用缓存表和汇总表时,必须决定是实时维护数据还是定期重建。哪个更好依赖于应用程序,但是定期重建并不只是节省资源,也可以保持表不会有很多碎片,以及有完全顺序组织的索引。

当重建汇总表和缓存表时,通常需要保证数据在操作时依然可用,这就需要通过使用影子表来实现,影子表指的是一张在真实表背后创建的表,当完成了建表操作后,可以通过一个原子的重命名操作切换影子表和原表。

为了提升读的速度,经常建一些额外索引,增加冗余列,甚至是创建缓存表和汇总表,这些方法会增加写的负担妈也需要额外的维护任务,但在设计高性能数据库时,这些都是常见的技巧,虽然写操作变慢了,但更显著地提高了读的性能。

二、视图与物化视图

1、视图

视图可以理解为一张表或多张表的与计算,它可以将所需要查询的结果封装成一张虚拟表,基于它创建时指定的查询语句返回的结果集。

查询者并不知道使用了哪些表、哪些字段,只是将预编译好的SQL执行,返回结果集。每次查询视图都需要执行查询语句。

2、物化视图

为了防止每次都查询,先将结果集存储起来,这种有真实数据的视图,称为物化视图。

MySQL并不原生支持物化视图,可以使用​​Justin Swanhart​​的开源工具​​Flexviews​​实现。

相对于传统的临时表和汇总表,​​Flexviews​​可以通过提取对源表的更改,增量地重新计算物化视图的内容。

三、加快alter table操作的速度

MySQL的alter table 操作的性能对大表来说是个大问题。MySQL执行大部分修改表结构的操作的方法使用新的结构创建一个空表,从旧表中查出所有数据插入新表,然后删除旧表。 这样操作可能需要花费很长时间,如果内存不足而表又很大,而且还有很多索引的情况下更为严重。

改善的方法有两种:

  • 第一种是先在一台不提供服务的机器上执行alter table操作,然后和提供服务的主表进行切换;
  • 第二种方式是通过影子拷贝,影子拷贝的技巧是用要求的表结构创建一张和源表无关的新表,然后通过重命名和删表的操作交换两张表。

四、计数器表

通常创建一张表来存储用户的点赞数、网站访问数等。

​create table like_count(num int unsigned not null) engine=InnoDB;​

每次点赞都会导致计数器进行更新:

​update like_count set num = num + 1;​

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

create table like_count(
slot tinyint unsigned not null primary key,
num int unsigned not null
) engine=InnoDB;

预先在这张表中新增10条数据,然后选择一个随机的槽slot进行更新:

注意:为了研究之后遇到的问题,后来又插入了一条~

MySQL进阶实战6,缓存表、视图、计数器表_缓存

update like_count set num = num + 1 where slot = floor(rand() * 10);

更新了两行,这是为什么呢?

MySQL进阶实战6,缓存表、视图、计数器表_数据_02

MySQL进阶实战6,缓存表、视图、计数器表_数据_03

​select一下,查询结果,有的时候0条,有的时候1条,有的时候2条,有的时候3条​​,惊呆了,这么有趣的事情,我怎么能放过,让我们一起一探究竟。

MySQL进阶实战6,缓存表、视图、计数器表_数据_04

MySQL进阶实战6,缓存表、视图、计数器表_数据_05

MySQL进阶实战6,缓存表、视图、计数器表_数据_06

让我们一起一探究竟:

  • floor() 函数的作用:返回小于等于该值的最大整数;
  • rand()函数的作用:获得0到1之间的随机值;

在ORDER BY或GROUP BY子句中使用带有RAND()值的列可能会产生意想不到的结果,因为对于这两个子句,RAND()表达式都可以对同一行计算多次,每次返回不同的结果。要从一组行中随机选择一个样本,将ORDER BY RAND()和LIMIT配合使用。

在MySQL的官方手册里,针对RAND()的提示大概意思就是,在ORDER BY从句里面不能使用RAND()函数,因为这样会导致数据列被多次扫描。

这就完了?

标签:汇总表,缓存,进阶,视图,查询,num,MySQL
From: https://blog.51cto.com/u_15559285/5890461

相关文章

  • Centos7 yum 安装mysql8.0
    1.去mysql官网下载yum存储库包https://dev.mysql.com/downloads/repo/yum/  这里本人很早之前就下载过,就不重复下载了 2.安装mysqlyum......
  • MySQL InnoDB存储引擎索引:数据结构与算法原理和优化概述
    大家早上好!今天我为大家讲解的是MySQLInnoDB存储引擎索引的数据结构与算法原理和优化概述,大致分为这个部分分别给大家进行介绍。首先我们来看一下MySQL整体的架构,MySQL大......
  • 数据库MySQL
    目录数据库MySQL一、数据库基础知识以及典型数据库MySQL简介1、存储数据的演变史2、数据库软件的应用史3.数据库的本质4.数据库的分类5.MySQL简介6.MySQL基本使用7.制作系......
  • Django视图层
    Django视图层目录Django视图层JsonResponseform表单上传文件及后端获取request对象方法CBV源码'''HttpResponse,返回字符串render,返回html页面,并且可以给html文件传值r......
  • MYSQL SQL语句查询关键字
    首先先创建一组数据createtableemp(idintprimarykeyauto_increment,namevarchar(20)notnull,genderenum('male','female')notnulldefault'male',......
  • springBoot mybatis-plus mySql代码生成器
    一、用到的依赖参考官网<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/X......
  • MySQL数据库之索引
    一、索引的概念索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址(类似于c语言的链表通过指针指向数据记录的内存地址)。使用索引后可......
  • MySQL数据库之用户管理
    一、数据库用户管理1.1新建用户 CREATEUSER'用户名'@'来源地址'[IDENTIFIEDBY[PASSWORD]'密码'];复制代码'用户名':指定将创建的用户名。'来源地址':指定新......
  • pymysql的使用
    importpymysql#连接数据库conn=pymysql.connect(host='101.133.225.166',user='root',password="123456",database='test',port=3306)##获取游标cursor=conn.......
  • 11.27MySQL周末总结
    目录§并发编程§一、线程理论1.本质2.特点3.创建线程的两种方式4.线程对象的其他方法5.同进程内多个线程数据共享二、互斥锁1.互斥锁的作用2.互斥锁lock三、GIL全局解释器......