Удалить все остальные строки, кроме номера строк в данном списке - PullRequest
1 голос
/ 17 ноября 2009

поэтому в основном вот что я хочу сделать: у меня есть таблица учетных записей, у меня есть список 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);

Я слышал, что этот запрос медленный, потому что он рекурсивный или что-то в этом роде. рассмотрим количество строк, которое у меня есть, это будет очень медленно . какой лучший способ сделать это?

Ответы [ 5 ]

4 голосов
/ 17 ноября 2009
delete from table
 where not acct_id in (3, 24, 515, 6326, etc.);

В зависимости от вида базы данных, индексов, распределенных или нет, и т. Д., Это может быть много работы. Альтернатива, которая эффективно работает даже в полностью журнализированных базах данных:

create table2 temp as /* create new table from the rows to keep */
   select *
   from table
   where acct_id in (3, 24, 515, 6326, etc.);
drop table;           /* discard table */
create table as       /* copy new table to rename */
  select * from table2;
drop table2;          /* get rid of temporary table */
0 голосов
/ 18 ноября 2009

Мое решение состоит в том, чтобы избежать DELETE и использовать таблицу TRUNCATE, потому что при удалении базы данных выполняется две операции. удалять и записывать записи в сегменты отката.

Конечно, это означает, что при усечении нет отката.

-- copy the few records into a temp table
select into temp 
 select * from account
 where acct_id in (3, 24, 515, 6326, 17);

-- truncate is super fast
truncate table account;

-- put back the few records
insert into account select * from temp;

drop table temp;
0 голосов
/ 17 ноября 2009

Не специфично для MySQL, но удаление в целом относительно дорого, потому что оно требует, чтобы механизм сделал кучу выборок, чтобы убедиться, что он удаляет правильные записи, а также фактические удаления. Вы также получите много транзакций, добавленных в журналы транзакций (конечно, в зависимости от движка и настроек).

Если у вас есть только небольшой набор записей, которые вы хотите сохранить, и большой набор, который вы хотите выбросить, то вы можете добиться гораздо более высокой производительности, обманывая ...

Вы копируете записи, которые хотите сохранить, и удаляете или усекаете таблицу, а затем добавляете «хранители» обратно.

0 голосов
/ 17 ноября 2009

Если у вас есть индекс для acct_id, я не вижу никакой причины, почему ваш запрос должен быть медленным. Насколько я знаю

in (3, 24, 515, 6326, 17)

- это просто синтаксический сахар для

acct_id != 3 AND acct_id != 24 ...

, который должен быть достаточно быстрым.

0 голосов
/ 17 ноября 2009

Ваш запрос мне подходит, но посмотрите на Explain, если вы пытаетесь оптимизировать свои запросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...