我有一个只有两列的 InnoDB 表,一个 VARCHAR(20) 和一个 DATETIME,以及大约 400 万行。该表用作其他表的黑名单,并且会不时从 csv 文件中截断和重新创建。除此之外没有涉及写入,它仅用于 SELECT 检查是否存在键,它总是命中 VARCHAR 列的索引。
问题是,我所有系统中的每一个操作都必须一直查询这个表,因为如果有匹配项,这是非常罕见的,则必须立即中止该操作。从我的应用程序分析中,我们花费了大约 10% 的数据库时间来读取它。
我正在考虑为此表使用内存引擎。这个想法是用只加载 csv 文件而不是整个数据导入操作的 CSV 引擎创建一个基表,以及一个初始化脚本来填充内存表。我假设 VARCHAR 列上的 HASH 索引对于简单查找来说会更快,但我不确定它在我拥有的几乎 100% 的未命中率下是否表现良好。
这是提高我的查找速度的好主意吗?
我不推荐MEMORY存储引擎
原因 #1:无冗余
无论是服务器崩溃还是系统正常关机,MEMORY 表中的所有数据都会丢失。您所拥有的只是表结构。
原因 #2:温和的磁盘 I/O
无论您选择什么存储引擎,
.frm
始终会访问表的 以检查表的存在性和可用性。这将为此检查产生一些磁盘 I/O。请阅读过去关于MEMORY 存储引擎优缺点的帖子
May 22, 2011
:我正在使用 MEMORY 存储引擎,但 MySQL 仍然写入我的磁盘...为什么?Sep 26, 2011
:让 MySQL 内存存储引擎使用 512 GB 的 RAM 是否可行?Jan 17, 2012
: Mysql 内存表获得很多锁Jan 20, 2012
:一个MEMORY表会占用多少内存?推荐
考虑到不使用 MEMORY 存储引擎的两个原因,我建议使用MyISAM存储引擎而不是使用 MEMORY 或 InnoDB。为什么?
回顾原因 #1,如果按如下方式创建表,则可以在 RAM 中拥有所有内容并在磁盘上拥有数据冗余:
步骤 01) 像这样创建表:
步骤 02) 为该表创建一个专用的 16MB MyISAM 缓存:
步骤 03) 将此添加到 /etc/my.cnf
步骤 04) 重启 MySQL
而已。
展望未来,表的每次重新加载都将填充专用键缓存。请注意
ROW_FORMAT=Fixed clause
。这样做的目的是将字符搜索速度提高 20-25%(我之前写过这个)。为什么不使用InnoDB?
使用MyISAM,数据保留在磁盘上,但只能从专用键缓存中访问。