什么是用于临时/旋转存储的最佳/最快 MySQL 表模式,例如会话管理?

Posted

技术标签:

【中文标题】什么是用于临时/旋转存储的最佳/最快 MySQL 表模式,例如会话管理?【英文标题】:What is the best/fastest MySQL Table Schema for temporary/rotating storage, e.g. for session management? 【发布时间】:2010-09-30 11:47:49 【问题描述】:

在为一个非常动态的网站编写自定义 mysql 数据库驱动的 php 会话管理时,您的会话表的最佳(最快读/写访问)结构是什么?

错误示例(未优化):

创建表`会话`( `session_id` VARCHAR(32) NOT NULL, `session_data` TEXT NOT NULL, `t_created` 日期时间不为空, `t_updated` 日期时间不为空, 主键(`session_id`) ) 引擎=INNODB 默认字符集=utf8;

我认为使用内存引擎会更好/更快,但我不确定。我想不出用英语解释所有内容的好方法,所以我列出了我认为很重要的要求/细节:

详情:

类别:优化 子类别:MySQL 查询性能 目标:最快的随机访问表架构和单行查询 常见用途:自定义会话管理、临时存储 操作系统:*nix,更具体地说:Centos 5+(在 x86_64 上) 数据库:MySQL 版本:5+(社区版)

结果:

SQL 查询:创建表 SQL 查询:按随机键选择单行(例如 PHP 会话 ID) SQL 查询:使用随机键插入单行(例如 PHP 会话 ID) SQL 查询:通过随机键(例如会话 ID)更新单行 SQL 查询:按时间戳删除多行(垃圾收集,例如过期会话)

预期的行寿命(例如会话持续时间):

30%:0s-30s 20%:30s-5m 30%:5m-1h 20%:1h-8h

预期的行数(例如活动会话):

低:128 中等:1024 高:100000

如果有人能想到更好的表达方式,请随时编辑。

【问题讨论】:

【参考方案1】:

您是否考虑过使用memcached 或APC 作为会话数据?这些几乎肯定会比任何 RDBMS 解决方案快得多。

如果您打算使用 MySQL 的另一个建议:不要使用 MEMORY 存储引擎,只需为各种缓存缓冲区启用大量内存即可。这样,数据将是持久的,由磁盘存储透明地支持,但在使用时可以快速使用。

【讨论】:

【参考方案2】:

你的直觉似乎是对的。我建议按如下方式创建表:

CREATE TABLE session (
  id CHAR(32) NOT NULL,
  data BLOB NOT NULL,
  t_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  t_updated TIMESTAMP,
  PRIMARY KEY (session_id),
  INDEX t_created(t_created),
  INDEX t_updated(t_updated)
)
ENGINE = MEMORY
CHARACTER SET utf8;

注意事项:

id - 如果您知道内容的长度,CHAR 的成本会更低 数据 - BLOB(二进制大对象)在这里更适用,因为您可能存储的内容可能不是 TEXT。 t_created 和 t_updated - TIMESTAMP - 计算速度更快,尽管您被限制在 1901-2038 的时间范围内,但这对于此应用程序来说应该没问题。 t_created 和 t_updated 上的 INDEX 占用大量内存且并非完全必要,但在通过这些列进行查询时,它们确实有助于提高性能。 MEMORY 表虽然速度非常快,但也有其局限性。如果您的 mysqld 重新启动,所有数据都将丢失。

旁注: 我不确定您打算如何对会话进行垃圾收集,但如果您预计 50% 的会话将在 5 分钟以下,那么如何定义会话结束?用户/客户是否必须明确结束他们的会话(通过注销)?如果您以如此快的速度隐式结束会话,您的用户可能会在您的网站上度过一段非常艰难的时光。

【讨论】:

注意:MEMORY 表不能包含BLOB(或TEXT)列 正如其他人指出的那样,内存表不起作用。我推荐 InnoDB,但要注意:utf8 每个字符使用 3 个字节,即使在内存中存储索引时它们不是 unicode。因此,您应该将 id 的字符集指定为 latin1。

以上是关于什么是用于临时/旋转存储的最佳/最快 MySQL 表模式,例如会话管理?的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL存储引擎InnoDB(三十五):临时表空间

MySQL:存储 MAC 地址的最佳方式?

CoreData:持久和临时存储

12 条用于 Linux 的 MySQL/MariaDB 安全最佳实践

使节点mysql运行最快的最佳技术?

使用 MySQL 生成非顺序、仅限整数的 UUID 的最快方法?