【问题标题】:Choose Mysql engine for processing a big "type-value" table选择 Mysql 引擎来处理一个大的“类型-值”表
【发布时间】:2011-06-15 03:41:14
【问题描述】:

我的任务是从数据库中删除操作期间未受影响的所有实体。我创建了一个单独的表,它有两列,第一个是表名,第二个是该表中记录的 id。

CREATE TABLE edited_entities (
        table VARCHAR(50) not null, 
        id BIGINT(20) not null)

例如,如果我有桌子

CREATE TABLE puppy(
        id BIGINT(20) not null, 
        name VARCHAR(20) not null)

里面有记录

id | name
1  | Rex

如果我编辑这条记录,我会将以下数据放入edited_entities:

table | id
puppy | 1

然后我需要删除所有未受影响的实体(id 不在edited_entities 表中),然后我执行以下操作:

delete from puppy where id not in 
    (select ee.id from edited_entities ee where ee.table= 'puppy');

我想知道这种操作(MySql)的最佳引擎是什么?默认的数据库引擎是 InnoDB。我考虑过内存(堆),但我不确定它是否可以加快删除操作。

如果您有建议我如何优化所需的操作,我会很高兴在这里。

我不想在小狗表中添加额外的列。

【问题讨论】:

  • 不同的 varchar 大小我猜不是故意的?

标签: mysql hashtable innodb b-tree in-memory-tables


【解决方案1】:

内存更快,因为它不必在事务结束时进入磁盘。在这种情况下,我会先尝试 BTREE 而不是 HASH 索引,因为它允许您使用部分复合索引,就像磁盘表一样。

还可以尝试使用准备好的语句进行插入和删除操作:在处理之前准备每个语句,然后使用相关参数调用。它可能更快,因为它不必解析 SQL;但在某些情况下,整个系统会因为占用大量内存而变慢。

另一个选项是实验性的“HandlerSocket”功能,可用于 MySQL 的多个分支,如Percona server,它允许您将 MySQL 表作为 NoSQL 存储访问,具有巨大的性能优势,但完全符合 ACID。 (Percona 人是性能狂热者;即使你不能使用 HandlerSocket,也一定要测试他们的 fork)

最后,一个可行的(但对您来说更多的工作)选项是一个单独的内存数据库。我倾向于使用Redis,这是一个非常高速的内存键值存储,并增加了“值”是有用的数据结构。在您的情况下,您可以为每个表存储一组 ID,例如

tokeep:puppy => 1,4,6,76.....

将元素添加到集合 (SADD tokeep:puppy 76) 是一个简单的(和原子的)操作,最后您将它们全部获取以创建 SQL DELETE WITH id NOT IN (...) 操作

而且,我想到的最后一个选项(还有更多工作要做)是将所有内容放在同一个存储中:有一个 Redis 的分支,以前称为 redisql,但现在是 Alchemy Database;它将 SQL 表添加到 Redis,保留了 NoSQL 的大部分性能优势。因此,您可以在 Alchemy 中将您的“常规”表作为 SQL 表,将您的“tokeep”集存储在同一服务器上的 NoSQL 上,最后执行以下操作:

DELETE FROM puppy WHERE id NOT IN ($SMEMBERS tokeep:puppy );

砰!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-06
    • 2011-06-06
    • 2011-09-20
    • 2012-05-11
    • 1970-01-01
    • 2022-12-31
    • 2013-04-23
    • 1970-01-01
    相关资源
    最近更新 更多