Usuń całą tabelę z wyjątkiem jednego wiersza


Powiedzmy, że mam bazę danych z tabelą zawierającą ponad 200 tys. Wierszy.

Ta tabela ma stałą krotkę o identyfikatorze 1800. reszta sekwencji krotek zaczyna się od 300k +.

Muszę wyczyścić tę tabelę, usunąć wszystkie rekordy bez usuwania jednego rejestru o identyfikatorze 1800. Wymyśliłem 3 rodzaje zapytań, które mogłem wykonać:
DELETE FROM table WHERE id > 1800
DELETE FROM table WHERE id <> 1800
DELETE FROM table WHERE id NOT IN (1800)

Mam wrażenie, że pierwsza jest szybsza od pozostałych, ale nie jestem pewien, ponieważ wszystkie inne dane mają identyfikatory znacznie powyżej 1800.
Który jest szybszy i dlaczego? Ponadto, jeśli istnieje szybszy sposób usuwania wpisów, z wyłączeniem tych, których nie można usunąć, daj mi znać.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Najszybszym sposobem w przypadku większości baz danych byłoby:
  • Wybierz rekord o identyfikatorze 1800 do tabeli tymczasowej
  • Usuwanie oryginalnego stołu
  • Skopiuj dane z tabeli tymczasowej do pełnej tabeli

Trzeba przyznać, że może to nie być możliwe ze względu na wyzwalacze, ograniczenia i uprawnienia. W wielu bazach danych możesz zrobić coś podobnego, modyfikując (2), aby obciąć tabelę zamiast ją upuszczać.
Jeśli chodzi o pierwotne pytanie, w zapytaniu dominuje obciążenie związane z faktycznym usuwaniem wierszy i powiązanych z nimi danych. To, jak dokonujesz porównania, nie ma znaczenia.
Przykładowy kod
create temp table saved as
select * from t where id = 1800truncate table tinsert into t
select * from saved

Nie jestem pewien co do konwencji nazewnictwa Postgres dla tabel tymczasowych, ale taka jest idea.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Dopóki wpływają na te same rekordy, będą miały taką samą wydajność.
Istnieje niewielka szansa, że ​​ten pierwszy użyje przeszukiwania indeksów zamiast bardziej wydajnego skanowania pełnej tabeli, ale jest to znikome.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jeśli nie możesz przenieść identyfikatora do nowej tabeli, możesz spróbować usunąć go w grupach lub partiach. Czasami transakcja z dużą porcją rekordów nie jest przetwarzana w najszybszy sposób. Dotyczy to dowolnej bazy danych Oracle i dołączonych do niej produktów bazodanowych Microsoft.
BEGIN TRANSACTION;
DELETE FROM table WHERE id >= 0 and id < 20000 and id != 1800;
COMMIT TRANSACTION;
BEGIN TRANSACTION;
DELETE FROM table WHERE id >= 20000 and id < 40000 and id != 1800;
COMMIT TRANSACTION;
etc
etc
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jeśli chcesz zachować tylko ostatni wpis i usunąć wszystkie inne wpisy, możesz użyć następującego zapytania, które zadziałało dla mnie
delete from public.table_name
WHERE lastrun_ts < ( select MAX(lastrun_ts)
FROM public.table_name
ORDER BY MAX(lastrun_ts) DESC
);

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się