删除给定列表中除行号之外的所有其他行
所以基本上这就是我想要做的:我有一个帐户表,我有一个 acct_id 列表:(3, 24, 515, 6326, 17),假设表中有大约 100,000 个帐户,最有效的方法是什么删除给定列表中除了包含 account_id 的行之外的所有其他行吗?
我想出了这样的想法:
delete from account where acct_id is not in (3, 24, 515, 6326, 17);
我听说这个查询很慢,因为它是递归的或者其他什么。考虑一下我拥有的行数,这会非常慢。有什么更好的方法来做到这一点?
so basically here's what I want to do: I have an account table, I have a list of acct_id: (3, 24, 515, 6326, 17), assuming I have about 100,000 accounts in the table, what's the most effective way to delete all the other rows besides the one with the account_id in my given list?
I came up with something like:
delete from account where acct_id is not in (3, 24, 515, 6326, 17);
I heard this query is slow because it's recursive or something. consider the number of rows I have, that would be very slow. what's a better way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
根据数据库风格、索引、分布式与否等,这可能需要大量工作。即使在完整日志数据库中也能有效工作的替代方案是:
Depending on the database flavor, indexes, distributed or not, etc., this could be a lot of work. The alternative which works efficiently even in fully-journaled databases is:
您的查询对我来说似乎很好,但请看一下
解释
如果您正在尝试优化查询。Your query seems fine to me, but take a look at
Explain
if you are trying to optimize your queries.如果您在 acct_id 上有索引,我看不出您的查询应该很慢的任何原因。
据我所知,
这只是语法糖,
应该足够快。
If you have got an index on acct_id I cannot see any reason why your query should be slow.
As far as I know
is just syntactic sugar for
which should be fast enough.
并非特定于 MySQL,但删除通常相对昂贵,因为它们需要引擎执行大量选择以确保它删除正确的记录以及实际的删除。您最终还会在事务日志中添加大量事务(当然取决于引擎和设置)。
如果您只有要保留的一小部分记录和要丢弃的一大组记录,那么您可以通过作弊获得更快的性能...
您复制要保留的记录,然后删除或截断表,然后将“守护者”添加回来。
Not specific to MySQL, but deletes in general are relatively expensive because they require the engine to do a bunch of selects to make sure it is deleting the right records as well as the actual deletes. You also wind up with a lot of transactions added to the transaction logs (depending on engine and settings of course).
If you only have a small set of records you want to keep and a large set you want to throw out, then you can get much fast performance by cheating...
You copy the records you want to keep and either drop or truncate the table, then add the "keepers" back in.
我的解决方案是避免 DELETE 并使用 TRUNCATE 表,因为删除数据库时会执行两个操作。删除记录并将其写入回滚段。
当然,这意味着截断时不会回滚。
My solution is to avoid DELETE and use TRUNCATE table because when you delete the database does two operations. delete and write records into rollback segments.
Of course, this means there is no rollback when you are truncating.