我正在编写一些需要将数据从分层格式压缩为表格格式的软件。我不是每次都在编程语言中完成所有操作并提供服务,而是希望将结果缓存几秒钟,并使用SQL进行排序和过滤。在使用时,我们在这几秒钟内讨论了400,000次写入和1次或2次读取。
每个表格包含3到15列。每行将包含100字节到2,000字节的数据,尽管在某些情况下,某些行可能会达到15,000字节。如果有必要,我可以剪辑数据以保持理智。
我正在考虑的主要选项是:
一个很好的选择,几乎专门为我的用例编写!但是......“MEMORY表使用固定长度的行存储格式。可变长度类型(如VARCHAR)使用固定长度存储.MEMORY表不能包含BLOB或TEXT列。” - 不幸的是,我的文本字段长度可达10,000个字符 - 甚至这个数字也没有特别限制。我可以根据文本列的最大长度调整varchar长度,因为我循环练习我的展平,但这并不完全优雅。另外,对于我偶尔的15,000个字符行,这是否意味着我需要为数据库中的每一行分配15,000个字符?如果有100,000行,那么1.3 gb不包括开销!
这是为了在云上运行,我可以轻松地启动一个16GB RAM的服务器,配置MySQL写入tmpfs并使用全功能的MySQL。我对此的关注是空间。虽然我确信工程师已编写内存引擎以防止消耗所有临时存储并使服务器崩溃,但我怀疑这个解决方案会知道何时停止。数据库格式时,我的2,000字节数据会消耗多少实际空间?我该如何监控?
索引 事实上,我事先会知道哪些列需要过滤和排序。我可以在插入之前设置索引,但是我真的可以期望在ram磁盘上获得什么样的性能提升?索引添加了多少额外开销?
插入 我假设用一个查询插入多行更快。但是一个查询或一系列大型查询存储在内存中,我们正在写入内存,所以如果我这样做,我会暂时需要加倍内存。那么我们谈论一次做一两个或一百个,并且在处理更多之前必须等待它完成.. InnoDB不会锁定表但我担心发送两个查询太靠近并且令人困惑MySQL的。这是一个有效的问题吗?有了MEMORY引擎,由于表锁,我必须等待完成。
临时 临时表是否有任何好处,除了它们在数据库连接关闭时被删除的事实?
答案 0 :(得分:2)
我建议你使用MyISAM。使用适合您的查询的索引创建表。然后禁用密钥,加载表,并启用密钥。
我建议你为你的系统开发这样的学科。我非常有效地使用过类似的学科。
保留表格的两份副本。拨打一个table_active
和第二个table_loading
。
在加载数据的新副本时,请使用这样的命令。
ALTER TABLE table_loading DISABLE KEYS;
/* do your insertions here, to table_loading */
/* consider using LOAD DATA INFILE if it makes sense. */
ALTER TABLE table_loading ENABLE KEYS; /* this will take a while */
/* at this point, suspend your software that's reading table_active */
RENAME TABLE table_active TO table_old;
RENAME TABLE table_loading TO table_active;
/* now you can resume running your software */
TRUNCATE TABLE table_old;
RENAME TABLE table_old TO table_loading;
或者,您可以DROP TABLE table_old;
为table_loading
而不是上次重命名创建新表。
这种双表(双缓冲)策略应该可以很好地运行。它会产生一些延迟,因为正在阅读表格的软件将在旧版本上运行。但是你会避免从一张未完全加载的表中读取。
我建议使用MyISAM,因为你不会耗尽RAM并且爆炸,你将不会有固定的行长开销或交易开销。但您也可以考虑使用MariaDB和Aria存储引擎,它可以很好地利用RAM缓冲区。
如果您确实使用MEMORY存储引擎,请务必调整max_heap_table_size
系统变量。如果您的读取查询将使用索引范围扫描(顺序索引访问),请确保指定BTREE样式索引。见这里:http://dev.mysql.com/doc/refman/5.1/en/memory-storage-engine.html