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