0

我的任务是从数据库中删除操作期间未受影响的所有实体。我创建了一个单独的表,它有两列,第一个是表名,第二个是该表中记录的 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。我考虑过内存(堆),但我不确定它是否可以加快删除操作。

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

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

4

1 回答 1

0

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

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

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

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

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

将元素添加到SADD tokeep:puppy 76集合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 );

砰!

于 2011-01-25T12:15:03.157 回答