2011-01-08 17 views
5

Mam tabelę w SQL Server 2008 (SP2) zawierającą 30 milionów wierszy, rozmiar tabeli 150 GB, jest kilka kolumn int i dwóch kolumn nvarchar (max): jeden zawierający tekst (od 1 -30000 znaków) i jeden zawierający xml (do 100000 znaków).Aktualizacja tabeli trwa bardzo długo

Tabela nie ma żadnych kluczy podstawowych ani indeksów (jest to tabela pomostowa). Więc używam zapytania:

UPDATE [dbo].[stage_table] 
SET [column2] = SUBSTRING([column1], 1, CHARINDEX('.', [column1])-1); 

kwerenda jest uruchomiona przez 3 godziny (i to nie jest jeszcze zakończone), co moim zdaniem jest zbyt długa. Czy to jest? Widzę, że istnieje stała szybkość odczytu 5 MB/s i szybkość zapisu 10 MB/s do pliku .mdf.

Jak mogę się dowiedzieć, dlaczego zapytanie działa tak długo? "Serwer" jest i7, 24GB RAM, dyski SATA RAID 10.

aktualizacja:

tabela zawiera jedną, dwie kolumny int nvarchar (20) i dwie kolumny nvarchar (max) kolumny. Kolumna 1 i Kolumny 2 w powyższej klauzuli aktualizacji są kolumnami nvarchar (20). "Duże" kolumny nie są aktualizowane.

Wielkie dzięki!

+0

Czy kolumny aktualizacji zostały zindeksowane? – IamIC

Odpowiedz

3

Szczerze mówiąc, to ogromna praca, którą wykonujesz (wyszukiwanie tekstu i zamiana na 150 gigabajtów). Jeśli dane etapowe pochodzą z bazy danych, można rozważyć wykonanie operacji tekstowych w tym miejscu, bez żadnego narzucania bazy danych.

+0

Dzięki za odpowiedź. Zaktualizowałem pytanie. Kolumna 1 i kolumna 2 to kolumny nvarchar (20), więc wyszukiwany tekst nie jest zbyt duży, tylko stół jest ogromny. – rrejc

+0

Podejrzewam, że nadal jest prawdą, że lepiej byłoby zrobić to poza bazą danych. Jest dużo narzutów w przetwarzaniu i aktualizowaniu każdego z tych wierszy - nie tak dużo, jak gdyby działałeś na całej bazie tekstowej, ale wciąż dużo. –

1

Robisz manipulację ciągami na polu - coś, z czego SQL jest notorycznie złe. Zastanów się, pisząc funkcję SQL CLR, która robi to, czego potrzebujesz, i użyj jej zamiast SUBSTRING([column1], 1, CHARINDEX('.', [column1])-1).

+0

Jeśli nie ma żadnych kryteriów wyboru, dlaczego brak indeksów ma znaczenie? – sgmoore

+1

Nie widzę, jak indeks może poprawić zapytanie. To musi być tylko pełne skanowanie tabeli. –

+2

Dlaczego indeks przyspiesza tę aktualizację? Nie ma klauzuli WHERE. W rzeczywistości dla tej aktualizacji indeks spowolniłby działanie (ze względu na czas potrzebny na aktualizację indeksów). –

0

Praktycznym sposobem na sprawdzenie, czy coś jest nietypowego, jest aktualizacja niektórych danych. Napisz widok, który wybiera, powiedz 10 000 najlepszych wierszy i uruchom aktualizację w stosunku do widoku.

Jeśli 10 000 wierszy aktualizuje się w sposób, który można by uznać za "normalny" dla serwera, oznacza to, że jest to "dużo danych do zaktualizowania".

Jeśli ta niewielka aktualizacja wydaje się niezbyt długa, należy sprawdzić więcej.

Przynajmniej to daje porządny poligon doświadczalny.

1

Praktycznym sposobem na sprawdzenie, czy coś jest nietypowego, jest aktualizacja niektórych danych. Napisz widok, który wybiera, powiedz 10 000 najlepszych wierszy i uruchom aktualizację w stosunku do widoku.

Jeśli 10 000 aktualizacji będzie wyglądać normalnie dla twojego serwera, oznacza to, że jest to "dużo danych do zaktualizowania".

Jeśli ta niewielka aktualizacja wydaje się niezbyt długa, należy zbadać więcej.

Przynajmniej to daje porządny poligon doświadczalny.

1

Istnieje kilka opcji tutaj. Ale bez dodatkowych informacji dotyczących tego, co zamierzasz zrobić z danymi po tej aktualizacji, odpowiedź Larry'ego Lustiga brzmi jak najbardziej odpowiednia. Ale inne opcje to:

  • Utwórz kolumnę 2 jako kolumnę obliczeniową zamiast kolumny fizycznej.
  • Wykonaj obliczenia podczas pobierania danych z tabeli pomostowej (co również ma miejsce w przypadku korzystania z poprzedniego punktu.)
  • Indeksuj kolumnę2, a następnie przeprowadź aktualizacje w porcjach zawierających 10 000 rekordów, w których kolumna 2 jest zerowy. Pozwoli to zachować niejawny wielkość transakcji w dół, który jest prawdopodobnie to, co jest obecnie zabija wydajność.
1

nie robiłem tego rodzaju przetwarzania w SQL Server, więc nie jestem pewien, czy Ta rada jest w pełni stosowana, ale jestem wystarczająco pewny, aby ją zasugerować.Co zwykle robię w Oracle, to unikanie aktualizacji całkowicie podczas przetwarzania WSZYSTKICH wierszy w sytuacji takiej, jak opisywana (pojedynczy użytkownik, wydarzenie wsadowe).

Albo migruję logikę z instrukcji aktualizacji z powrotem do instrukcji, która wstawiła wiersze. Jeśli nie jest to możliwe, tworzę nową tabelę i umieszczam logikę aktualizacji na liście wyboru. Na przykład, zamiast robić

UPDATE [dbo].[stage_table] 
SET [column2] = SUBSTRING([column1], 1, CHARINDEX('.', [column1])-1); 

zrobiłbym:

create table stage_table2 as 
    select column1 
     ,substring(column1, 1, charindex('.', column1)-1) as column2 
     ,column3 
     ,column4 
    from stage_table; 

drop table stage_table; 

alter table stage_table2 rename to stage_table; 
-- re-create indexes and constraints, optionally gather statistics 

mogę również zrobić z zapytaniem równoległego i opcji NOLOGGING generować bardzo mało przerobić i bez cofania w ogóle, które przewyższają komunikat aktualizacyjny z tak dużym marginesem nie jest nawet zabawny :) Oczywiście jest tak ze względu na wewnętrzne Oracle, ale myślę, że byłoby możliwe jego replikowanie za pomocą SQL Server. W Twoim opisie jest coś, co może sprawić, że będzie to mniej skuteczne podejście. Miałeś naprawdę duże kolumny tekstowe, które musiałbyś "przeciągnąć" w instrukcji CTAS.

Należy również sprawdzić konfigurację sprzętu, ponieważ nie jest odpowiednia do pracy z ilością danych, które zostały na nią wysłane. Albo coś jest nie tak z konfiguracją, lub masz dużo innej działalności dzieje:

widzę, że tam jest stały czytać stopę 5MB/s i pisać szybkość 10 MB/s do. plik mdf.

Mogę pokonać to na moim 2 letnim laptopie mojej dziewczyny. Biorąc pod uwagę szybkość odczytu 5 mb/s i tabelę o pojemności 150 GB, skanowanie tylko raz w ciągu 8,5 godziny zajmie 8,5 godziny. Zakłada to, że baza danych dodaje 0% kosztów ogólnych, czyli , a nie.

Powiązane problemy