Jaka jest zalecana wielkość partii SqlBulkCopy
? Szukam ogólnej formuły, której mógłbym użyć jako punktu wyjścia do dostrojenia wydajności.
źródło
Jaka jest zalecana wielkość partii SqlBulkCopy
? Szukam ogólnej formuły, której mógłbym użyć jako punktu wyjścia do dostrojenia wydajności.
Mam narzędzie do importowania znajdujące się na tym samym serwerze fizycznym, co moja instancja programu SQL Server. Używając niestandardowego IDataReader
, analizuje płaskie pliki i wstawia je do bazy danych przy użyciu SQLBulkCopy
. Typowy plik ma około 6 milionów kwalifikowanych wierszy, średnio 5 kolumn dziesiętnego i krótkiego tekstu, około 30 bajtów na wiersz.
Biorąc pod uwagę ten scenariusz, stwierdziłem, że rozmiar partii 5000 jest najlepszym kompromisem między szybkością i zużyciem pamięci. Zacząłem od 500 i eksperymentowałem z większymi. Okazało się, że 5000 jest średnio 2,5 razy szybsze niż 500. Wstawienie 6 milionów wierszy zajmuje około 30 sekund przy wielkości partii 5000 i około 80 sekund przy wielkości partii 500.
10 000 nie było mierzalnie szybsze. Przejście do 50 000 poprawiło prędkość o kilka punktów procentowych, ale nie jest warte zwiększonego obciążenia serwera. Powyżej 50000 nie wykazano poprawy szybkości.
To nie jest formuła, ale to kolejny punkt danych, którego możesz użyć.
Jest to kwestia, nad którą też spędziłem trochę czasu. Chcę zoptymalizować importowanie dużych plików CSV (ponad 16 GB, ponad 65 milionów rekordów i rosnących) do bazy danych SQL Server 2005 przy użyciu aplikacji konsoli C # (.Net 2.0). Jak Jeremy ma już wspomniano , trzeba będzie zrobić kilka dostrojenie do konkretnych okoliczności, ale polecam masz początkową wielkość wsadu 500, a badanie wartości powyżej i poniżej tego.
Otrzymałem zalecenie, aby przetestować wartości od 100 do 1000 dla wielkości partii z tego postu na forum MSDN i byłem sceptyczny. Ale kiedy testowałem partie o wielkości od 100 do 10 000, stwierdziłem, że 500 to optymalna wartość dla mojej aplikacji. Wartość 500 dla
SqlBulkCopy.BatchSize
zaleca się również tutaj .Aby jeszcze bardziej zoptymalizować działanie SqlBulkCopy, zapoznaj się z tą poradą MSDN ; Uważam, że użycie SqlBulkCopyOptions.TableLock pomaga skrócić czas ładowania.
źródło
Jak powiedzieli inni, zależy to od środowiska, w szczególności wielkości wiersza i opóźnienia sieci.
Osobiście zacznę od ustawienia
BatchSize
właściwości na 1000 wierszy i zobaczę, jak to działa. Jeśli to zadziała, podwajam liczbę wierszy (np. Do 2000, 4000 itd.), Aż otrzymam limit czasu.W przeciwnym razie, jeśli przekroczenie limitu czasu nastąpi przy 1000, zmniejszam liczbę wierszy o połowę (np. 500), aż zadziała.
W każdym przypadku podwajam (jeśli się powiedzie) lub zmniejszam o połowę (jeśli się nie udaje) różnicę między każdą z dwóch ostatnich prób wielkości partii, aż do znalezienia idealnego punktu.
Innym czynnikiem, który należy wziąć pod uwagę, jest to, jak długo trwa kopiowanie pojedynczej partii wierszy. Limity czasu wystąpią, jeśli partia kopiowanych wierszy przekroczy
BulkCopyTimeout
właściwość, która domyślnie wynosi 30 sekund. Możesz spróbować podwoić tęBulkCopyTimeout
właściwość do 60 sekund. Pozwala to na skopiowanie większego zestawu wierszy partii przez dłuższy czas. Na przykład partia 50000 wierszy może zająć około 40 sekund po przekroczeniu 30-sekundowego limitu czasu, więc zwiększenie wydajności do 60 sekund może pomóc w zwiększeniu wydajności.źródło
Wszystko zależy od Twojej implementacji.
Jakiej prędkości możesz oczekiwać w swojej sieci? Czy używasz go w Forms czy w ASP.Net? Czy musisz ostrzegać użytkownika o postępach? Jaka jest łączna wielkość pracy?
Z mojego doświadczenia wynika, że uruchomienie kopiowania zbiorczego bez określonego rozmiaru partii spowoduje problemy z przekroczeniem limitu czasu. Lubię zaczynać od około 1000 płyt i stamtąd wprowadzać pewne poprawki.
źródło
Próbowałem wielu rozmiarów, w moim przypadku 5000 było dobre
źródło