2011-07-28 12 views
8

Podczas wykonywania tego prosty SQL DELETE, Dostaję timeout z SQL Server:Proste SQL DELETE dając czas oczekiwania

DELETE FROM dbo.[User] WHERE Id = 95146 

Istnieje około 95.000 pozycji w tabeli.

Pomyślałem, że może to być spowodowane indeksami na stole, więc usunąłem wszystkie oprócz klucza podstawowego (Id), który jest klastrowany, ale to nie pomogło.

Usunąłem wszystkie statystyki, które utworzyłem, ale także bez żadnego efektu.

Co jeszcze mogę zrobić, aby zoptymalizować?

poważaniem, David

+1

Proszę oznaczyć i/lub określić, której wersji programu SQL Server używasz. Ta informacja jest zawsze pomocna, ponieważ niektóre podejścia do problemu mogą być lub nie być odpowiednie w przypadku niektórych wersji. –

Odpowiedz

13

Ilu zagranicznych klucze masz odwołanie do kolumny UsersId, a tam są indeksy na tych kolumnach?

Jeśli kaskada jest ustawiona jako NO_ACTION, jak już wspomniano, czas może być poświęcony przez SQL Server, który musi wykonać pełne skanowanie tabeli na każdej z tych tabel, aby upewnić się, że nie ma odniesienia do Id 95146 - I ' Widziałem, że łatwo to zająć kilka minut, jeśli inne stoły są duże.

+0

W rzeczywistości jest 20 takich kluczy obcych wskazujących na identyfikator użytkownika, więc myślę, że to jest problem. Przejdę przez te, żeby sprawdzić indeksy. – dgivoni

+0

OK, to był powód. Po dodaniu indeksu do tych kluczy obcych, limit czasu zniknął. Dzięki za pomoc – dgivoni

3

To bardzo dziwne. Domyślam się, że masz klucz obcy ON CASE CASE, który odwołuje się do tabeli Users w innym miejscu twojego schematu. Sprawdź swoje ograniczenia:

SELECT f.name AS ForeignKey, 
    OBJECT_NAME(f.parent_object_id) AS TableName, 
    COL_NAME(fc.parent_object_id,fc.parent_column_id) AS ColumnName, 
    OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName, 
    COL_NAME(fc.referenced_object_id, 
    fc.referenced_column_id) AS ReferenceColumnName, 
    f.delete_referential_action_desc 
FROM sys.foreign_keys AS f 
INNER JOIN sys.foreign_key_columns AS fc 
ON f.OBJECT_ID = fc.constraint_object_id 
+0

Mam cudzysłów odniesienia, ale uruchomienie powyższego pokazuje wszystkie z nich mieć NO_ACTION w kolumnie delete_referencial_action_desc. – dgivoni

+0

Nie wymagają kaskadowania, aby spowodować problemy - należy sprawdzić każdą wartość kolumny klucza obcego, aby nie zawierała ona wartości, którą usuwasz, dlatego jeśli nie ma indeksu w tej kolumnie, być skanowaniem tabeli. – cjk

+0

Ok, rozumiem. Przejrzę te, żeby sprawdzić. – dgivoni

2

Podczas gdy wyciąg jest uruchomiony, spójrz na listę uruchomionych zadań i blokad wyjętych przez system. Możesz uzyskać te informacje z Monitora aktywności lub możesz przeglądać uruchomione zadania w widoku sys.dm_os_waiting_tasks i blokuje się przy pomocy exec sp_lock i sys.dm_tran_locks.

Ponadto w SQL Server Management Studio wprowadź tę instrukcję i spójrz na szacowany plan wykonania. Być może będziesz mógł zobaczyć, co SQL Server próbuje zrobić.

Zobacz zagraniczne klucze do tego stołu. Aby zoptymalizować asercje kluczy obcych, konieczne może być dodanie indeksów do innych tabel.

0

Oprócz innych odpowiedzi, być może twoje DELETE jest blokowane przez jakąś inną aktywność (zobacz, czy jest jakaś wartość w kolumnie BlkBy sp_who2 dla twojego spid), lub może jest wyzwalacz w tabeli, który jest robienie czegoś niezdrowego. Większość wspomnianych rzeczy spowolni usuwanie, ale z wyjątkiem bardzo skomplikowanych sytuacji, które nie są wystarczająco znaczące, aby spowodować przekroczenie limitu czasu.

3

Zmagałem się z oświadczeniem DELETE, które powodowało, że nasz system ERP (Epicor 10) przestał działać w swoim nocnym uruchomieniu MRP. Było to usunięcie z kilkoma sprzężeniami, a jedna z tabel uczestniczących w łączeniu jest dość duża. Dziwne było to, że jeśli przekształciłem to usuwanie w SELECT * dla tej samej klauzuli join/where, zapytanie zakończy się natychmiastowo i będzie miało wyniki ZERO (tj. Instrukcja delete oczywiście wykonała długie skanowanie dużych tabel, ale nie zrobiła tego ". t faktycznie znaleźć coś do usunięcia).

Co w końcu pomogło mi to, że uruchomiłem wersję z wybraną wersją z Pokaż rzeczywisty plan wykonania włączony, a to miało sugerowany Indeks Niepowtarzalny do dodania do jednej z tabel. Po dodaniu tego indeksu instrukcja select nadal działała od razu, ale teraz instrukcja delete też działała!

Powiązane problemy