MySQL Usuń wszystkie wiersze z tabeli i zresetuj identyfikator do zera

183

Muszę usunąć wszystkie wiersze z tabeli, ale kiedy dodam nowy wiersz, chcę, aby identyfikator klucza podstawowego, który ma automatyczny przyrost, zaczął ponownie od 0 odpowiednio od 1.

marek_lani
źródło

Odpowiedzi:

304

Nie usuwaj, użyj obcięcia:

Truncate table XXX

Moduł obsługi tabel nie pamięta ostatnio użytej wartości AUTO_INCREMENT, ale zaczyna odliczanie od początku. Dotyczy to nawet MyISAM i InnoDB, które zwykle nie używają ponownie wartości sekwencji.

Źródło .

Francois
źródło
20
Obcinanie działa dobrze z tabelami bez ograniczeń, ale jeśli tabela ma ograniczenie klucza obcego, możesz rozważyć użycie metody Usuń. Zobacz ten post, jeśli masz ograniczenia FK: obetnij ograniczoną tabelę klucza obcego
Julian Soro
1
pamiętajcie, że tabela okrojona nie będzie się wycofywać
penny chan
83

Jeśli nie możesz użyć TRUNCATE(np. Z powodu ograniczeń klucza obcego), możesz użyć tabeli zmian po usunięciu wszystkich wierszy, aby zrestartować auto_increment:

ALTER TABLE mytable AUTO_INCREMENT = 1
koń bez imienia
źródło
3
@NBhargav Ponieważ możesz używać silnika InnoDB na stole zamiast MyISAM, pierwsze nie obsługują resetowania indeksu.
Gustavo Rubio
jak usunąć wszystkie wiersze przed zmianą wartości auto_increment
Kasun Siyambalapitiya
@KasunSiyambalapitiya DELETE FROM tablename;(ale to nie zadziała dobrze, gdy istnieją ograniczenia FK - patrz stackoverflow.com/a/5452798/507761 )
Matthew Czytaj
17

Jeśli tabela ma klucze obce, zawsze używam następującego kodu:

SET FOREIGN_KEY_CHECKS = 0; -- disable a foreign keys check
SET AUTOCOMMIT = 0; -- disable autocommit
START TRANSACTION; -- begin transaction

/*
DELETE FROM table_name;
ALTER TABLE table_name AUTO_INCREMENT = 1;
-- or
TRUNCATE table_name;
-- or
DROP TABLE table_name;
CREATE TABLE table_name ( ... );
*/

SET FOREIGN_KEY_CHECKS = 1; -- enable a foreign keys check
COMMIT;  -- make a commit
SET AUTOCOMMIT = 1 ;

Różnica dotyczy czasu wykonania. Spójrz na odpowiedź Sorina.

czarny
źródło
2
Jest to dobry sposób na posiadanie osieroconych danych w dowolnej tabeli, które obce klucze do tabeli, którą wymazujesz. Włączenie sprawdzania klucza obcego po fakcie nie powoduje, że MySQL ponownie sprawdza poprawność tych kluczy obcych, o ile mi wiadomo. To pozostawia wiersze zawierające dane, które nie istnieją w tabeli referencyjnej. Równie dobrze możesz nie mieć w ogóle obcych kluczy na stole.
cimmanon
8

Ciekawy fakt.

Byłem pewien, TRUNCATEzawsze będzie lepiej, ale w moim przypadku, na bazie danych z około 30 tabel z kluczy obcych, zaludnionych tylko kilka wierszy, zajęło to około 12 sekund do TRUNCATEwszystkich tabel, w przeciwieństwie do zaledwie kilkuset milisekund do DELETEwydziwianie. Ustawienie automatycznego przyrostu daje w sumie około sekundy, ale wciąż jest o wiele lepsze.

Proponuję więc wypróbować oba, aby zobaczyć, który z nich działa szybciej w twoim przypadku.

Sorin
źródło
2

jeśli chcesz użyć, truncateużyj tego:

SET FOREIGN_KEY_CHECKS = 0; 
TRUNCATE table $table_name; 
SET FOREIGN_KEY_CHECKS = 1;
david2020
źródło