前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL计数器、每日计数器表设计与调优

MySQL计数器、每日计数器表设计与调优

作者头像
Java架构师必看
发布2021-05-14 17:38:39
2.2K0
发布2021-05-14 17:38:39
举报
文章被收录于专栏:Java架构师必看Java架构师必看

计数器

如果应用在表中保存计数器,则在更新计数器时可能碰到并发问题。计数器表在Web应用中很常见。可以用这种表缓存一个用户的朋友数、文件下载次数等。创建一张独立的表存储计数器通常是个好主意,这样可使计数器表小且快。使用独立的表可以帮助避免查询缓存失效,并且可以使用本节展示的一些更高级的技巧。 应该让事情变得尽可能简单,假设有一个计数器表,只有行数据,记录网站的点击次数:

代码语言:javascript
复制
CREATE TABLE hit_counter ( 
    cnt INT UNSIGNED NOT NULL 
) ENGINE = INNODB;

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

代码语言:javascript
复制
UPDATE hit_counter SET cnt = cnt+ 1;

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

代码语言:javascript
复制
CREATE TABLE hit_counter ( 
	slot TINYINT UNSIGNED NOT NULL PRIMARY KEY,
	cnt INT UNSIGNED NOT NULL
) ENGINE = INNODB;

然后预先在这张表增加100行数据。现在选择一个随机的槽 (slot) 进行更新:

代码语言:javascript
复制
UPDATE hit_counter SET cnt = cnt + 1 WHERE slot = RAND() * 100;

要获得统计结果,需要使用下面这样的聚合查询:?

代码语言:javascript
复制
SELECT SUR(cnt) FROM hit_counter;

每日计数器

另外一个常见的需求是每隔一段时间开始一个新的计数器(例如,每天一个)。如果需要这么做,则可以再简单地修改一下表设计:

代码语言:javascript
复制
CREATE TABLE dally_hit_counter (
	day DATE not null,
	slot TINYINT UNSIGNED NOT NULL,
	cnt INT UNSIGNED NOT NULL,
	primary key(day, slot)
)ENGINE = INNODB;

在这个场景中会,可以不用像前面的例子那样预先生成行,而用ON DUPLICATE KEY UPDATE进行代替

代码语言:javascript
复制
INSERT INTO `dally_hit_counter` ( DAY, slot, cnt )
VALUES
	( CURRENT_DATE, RAND( ) * 100, 1 ) 
	ON DUPLICATE KEY UPDATE cnt = cnt + 1;

?如果希望减少表的行数,以避免表变得太大,可以写一个周期执行的任务,合并所有结果到0号槽,并且删除所有的槽。

代码语言:javascript
复制
UPDATE daily_hit_counter as c
	INNER JOIN (
		SELECT day, SUM(cnt) as cnt, MIN(slot) as mslot
		FROM daily_hit_counter
		GROUP BY day
		) AS x USING(day)
	SET c.cnt = IF(c.slot = x.mslot, x.cnt, 0),
			c.slot = IF(c.slot = x.mslot, 0, c.slot);

内容参考自《高性能MySQL》 P135

本文来源itcats_cn,由javajgs_com转载发布,观点不代表Java架构师必看的立场,转载请标明来源出处

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 计数器
  • 每日计数器
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com