2011-01-10 11 views
5

Podane: SQL Server 2008 R2. Zamknij niektóre płyty z danymi speedin. Dyski z logami są opóźnione.Optymalizacja wydajności masywnych wkładek ...?

Wymagane: WIELE UMIESZCZA WIELE części wkładek. Jak 10.000 do 30.000 wierszy do prostej tabeli z dwoma indeksami na sekundę. Wkładki mają wewnętrzną kolejność i nie będą się powtarzać, ponieważ taka kolejność wstawek nie może być utrzymywana w krótkim czasie (tj. Wiele równoległych wstawek jest w porządku).

Do tej pory: gromadzenie danych w kolejce. Regularnie (async threadpool) opróżnia do 1024 wpisów do elementu pracy, który zostanie umieszczony w kolejce. Threadpool (klasa niestandardowa) ma 32 możliwe wątki. Otwiera 32 połączenia.

Problem: wydajność jest wyłączona przez współczynnik 300 ... tylko około 100 do 150 wierszy zostało wstawionych na sekundę. Czas oczekiwania na logu wynosi do 40% - 45% czasu przetwarzania (ms na sekundę) w serwerze sql. Obciążenie procesora serwera jest niskie (od 4% do 5%).

Nie nadaje się do użytku: wkładka zbiorcza. Dane muszą być zapisane na dysku w czasie rzeczywistym w miarę możliwości. Jest to w zasadzie archiwizowany proces przesyłania danych przez system, ale istnieją zapytania, które wymagają regularnego dostępu do danych. Mógłbym spróbować wyrzucić je na dysk i używając przesyłania zbiorczego 1-2 razy na sekundę .... spróbuję.

Czy ktoś jest mądrym pomysłem? Moim następnym krokiem jest przeniesienie dziennika do szybkiego zestawu płyt (128 gb nowoczesnych ssd) i zobaczenie, co się wtedy stanie. Znaczący wzrost wydajności prawdopodobnie spowoduje zupełnie inne zmiany. Ale nawet wtedy .... pytanie brzmi, czy/co jest wykonalne.

Więc proszę, odpal inteligentne pomysły.

+3

czy kiedykolwiek uzyskać ostateczne rozwiązanie do tego? – Carth

Odpowiedz

4

Ok, za mnie. Będziemy próbować SqlBulkCopy, wsypując do 65536 wpisów i wypuszczając je co sekundę w sposób asynchroniczny. Będzie raportować o zyskach.

+3

Osiąga się 75.000 rekordów na sekundę przy użyciu 3 wątków. – TomTom

+0

Wow, to całkiem imponujące, miła robota! –

3

Przechodzę tutaj dokładnie ten sam problem, więc przejdę przez kolejne kroki, które poprawię swoją wydajność.

  • Oddzielna dziennika i pliku DBF na różnych zestawach wrzeciona
  • używać podstawowego odzyskiwania
  • że nie wspomina o żadnych wymagań indeksowania innych niż fakt, że kolejność nie jest ważna wstawkami - w tym nie należy używać indeksów klastrowych w przypadkach innych niż kolumna tożsamości.
  • Rozpocznij ponownie skalowanie współbieżności od 1 i zatrzymaj się, gdy wydajność spadnie; cokolwiek ponad to prawdopodobnie zaszkodzi wydajności.
  • zamiast upuszczać na dysk do bcp, a podczas korzystania z programu SQL Server 2008 należy rozważyć wstawianie wielu wierszy naraz; To stwierdzenie wprowadza trzy rzędy w jednym połączenia SQL

    INSERT na wartości w tabeli (1,2,3), (4,5,6), (7,8,9)

ja na czubku ~ 500 różnych insertów na sekundę z jednego wątku. Po wykluczeniu sieci i procesora (0 zarówno na kliencie, jak i na serwerze), założyłem, że należy obciążyć dyskiem io na serwerze, jednak wstawienie w partiach po trzy dostarczyło mi 1500 insertów na sekundę, co wyklucza dysk io.

Jest oczywiste, że biblioteka klienta MS ma górny limit zapakowany w nią (i zanurzenie w reflektorze pokazuje jakiś włochaty kod zakończenia asynchronizacji).

Batchowanie w ten sposób, oczekiwanie na zdarzenia x, które mają zostać odebrane przed wywołaniem insert, powoduje, że teraz wstawiam ~ 2700 insertów na sekundę z jednego wątku, który wydaje się być górną granicą dla mojej konfiguracji.

Uwaga: jeśli nie masz stałego strumienia zdarzeń przychodzących przez cały czas, możesz rozważyć dodanie timera, który opróżnia twoje wstawki po pewnym okresie (aby zobaczyć ostatnie wydarzenie dnia!)

1

Niektóre propozycje dla zwiększenia wydajności insert:

  • Wzrost ADO.NET BatchSize
  • Wybierz indeksu klastrowego tabeli docelowej mądrze, tak, że wkładki nie doprowadzi do indeksu klastrowego podziałów węzłów (np autoinc kolumna)
  • wstawić do tabeli tymczasowej sterty, potem wydać jeden wielki „wstawić po wybierz” Oświadczenie naciskać wszystkie dane tabeli tymczasowej do rzeczywistej tabeli docelowej
  • Zastosuj SqlBulkCopy
  • Wybierz „Luzem Zapisane” odzyskiwanie modelu instad z „Full” model odzyskiwania
  • Place blokada tabeli przed włożeniem (jeśli scenariusz biznesowy na to pozwala)

Zrobione z Tips For Lightning-Fast Insert Performance On SqlServer