SQL Server: maksymalna liczba wierszy w tabeli [zamknięta]

80

Tworzę oprogramowanie, które przechowuje wiele danych w jednej ze swoich tabel bazy danych (SQL Server w wersji 8, 9 lub 10). Powiedzmy, że dziennie do tej tabeli jest wstawianych około 100 000 rekordów. To około 36 milionów rekordów rocznie. W obawie, że stracę na wydajności, postanowiłem codziennie tworzyć nową tabelę (tabelę z aktualną datą w nazwie), aby zmniejszyć liczbę rekordów w tabeli.

Czy mógłbyś mi powiedzieć, czy to był dobry pomysł? Czy istnieje limit rekordów dla tabel serwera SQL? A może wiesz, ile rekordów (mniej lub więcej) można przechowywać w tabeli, zanim wydajność zostanie znacznie obniżona?

Mariusz Schimke
źródło
33
„Programiści tracą ogromne ilości czasu na myślenie lub martwienie się o szybkość niekrytycznych części swoich programów, a te próby zwiększenia wydajności mają w rzeczywistości silny negatywny wpływ na debugowanie i konserwację. Powinniśmy zapomnieć o małych wydajnościach, powiedzmy o 97% przypadków: przedwczesna optymalizacja jest źródłem wszelkiego zła. Jednak nie powinniśmy przepuszczać naszych możliwości w tych krytycznych 3% ”. Knuth 1974
Matthew Lock,

Odpowiedzi:

36

Trudno udzielić ogólnej odpowiedzi na to pytanie. To naprawdę zależy od wielu czynników:

  • jaki jest rozmiar twojego rzędu
  • jakiego rodzaju dane przechowujesz (ciągi, bloby, liczby)
  • co robisz ze swoimi danymi (po prostu przechowuj je jako archiwum, regularnie sprawdzaj)
  • czy masz indeksy na swoim stole - ile
  • jakie są specyfikacje twojego serwera

itp.

Jak podano w innym miejscu tutaj, 100 000 dziennie, a zatem na stół to przesada - sugerowałbym miesięczne lub tygodniowe, a może nawet kwartalne. Im więcej masz tabel, tym większy będzie koszmar konserwacji / zapytań.

Rashack
źródło
13
Chciałbym wzmocnić „większy koszmar konserwacji / zapytań” - z własnego doświadczenia unikałbym podziału na tabele jak zarazy.
Daniel James Bryars,
92

Oto niektóre specyfikacje maksymalnej wydajności dla programu SQL Server 2008 R2

  • Rozmiar bazy danych: 524,272 terabajty
  • Bazy danych na wystąpienie programu SQL Server: 32767
  • Grupy plików na bazę danych: 32767
  • Pliki na bazę danych: 32767
  • Rozmiar pliku (dane): 16 terabajtów
  • Rozmiar pliku (log): 2 terabajty
  • Wiersze na tabelę: ograniczone dostępnym miejscem do przechowywania
  • Tabele na bazę danych: Ograniczone liczbą obiektów w bazie danych
Malak Gerges
źródło
22
Podejrzewam, że jeśli masz więcej niż 9 223 372 036 854 775 807 wierszy, napotkasz jednak problemy (maksymalny rozmiar a bigint)
Martin Smith
11
Czy kiedykolwiek obliczyłeś liczbę lat potrzebną do uzyskania tej liczby wierszy przy 100000 wierszy / dzień wspomnianego PO?
Erwin Smout
75
Wysyłanie tego dla leniwych: 252 695 124 lat.
NotMe
18
@NotMe Nie ożywiać i czepiać się, ale mam 252695124297 lat. (Czasami żałuję, że nie jestem z tej leniwej populacji, o której wspomniałeś)
filthyfool
4
@philthyfool Jeden dzień w roku przestępnym to ogromna różnica. Otrzymuję 252,522,163,911. Poza tym to były doskonałe minuty w moim życiu, których nie mogę teraz odzyskać.
Suamere
53

Mam tabelę z trzema kolumnami z nieco ponad 6 miliardami wierszy w programie SQL Server 2008 R2.

Codziennie wykonujemy zapytania, aby tworzyć wykresy analizy systemu minuta po minucie dla naszych klientów. Nie zauważyłem żadnych spadków wydajności bazy danych (chociaż fakt, że rośnie ona o ~ 1 GB każdego dnia, sprawia, że ​​zarządzanie kopiami zapasowymi jest nieco bardziej skomplikowane, niż bym chciał).

Aktualizacja lipiec 2016

Liczba wierszy

Udało nam się osiągnąć ~ 24,5 miliarda wierszy, zanim kopie zapasowe stały się na tyle duże, że mogliśmy zdecydować o obcięciu rekordów starszych niż dwa lata (~ 700 GB przechowywanych w wielu kopiach zapasowych, w tym na drogich taśmach). Warto zauważyć, że występ nie był istotnym motywatorem w tej decyzji (tj. Nadal działał świetnie).

Gorąco polecam ten artykuł każdemu, kto próbuje usunąć 20 miliardów wierszy z SQL Server . Odpowiedni kod na wypadek utraty linku (przeczytaj artykuł, aby uzyskać pełne wyjaśnienie):

ALTER DATABASE DeleteRecord SET RECOVERY SIMPLE;
GO

BEGIN TRY
    BEGIN TRANSACTION
        -- Bulk logged 
        SELECT  *
        INTO    dbo.bigtable_intermediate
        FROM    dbo.bigtable
        WHERE   Id % 2 = 0;

        -- minimal logged because DDL-Operation 
        TRUNCATE TABLE dbo.bigtable;  

        -- Bulk logged because target table is exclusivly locked! 
        SET IDENTITY_INSERT dbo.bigTable ON;
        INSERT INTO dbo.bigtable WITH (TABLOCK) (Id, c1, c2, c3)
        SELECT Id, c1, c2, c3 FROM dbo.bigtable_intermediate ORDER BY Id;
        SET IDENTITY_INSERT dbo.bigtable OFF;
    COMMIT
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK
END CATCH

ALTER DATABASE DeleteRecord SET RECOVERY FULL;
GO

Aktualizacja listopad 2016

Jeśli planujesz przechowywać tak dużo danych w jednej tabeli: nie rób tego. Zdecydowanie zalecam rozważenie partycjonowania tabel (ręcznie lub za pomocą wbudowanych funkcji, jeśli używasz wersji Enterprise). To sprawia, że ​​usuwanie starych danych jest tak łatwe, jak obcinanie tabeli raz w tygodniu (tydzień / miesiąc / itd.). Jeśli nie masz Enterprise (czego my nie mamy), możesz po prostu napisać skrypt, który będzie uruchamiany raz w miesiącu, usunie tabele starsze niż 2 lata, utworzy tabelę na następny miesiąc i ponownie wygeneruje dynamiczny widok, który łączy całą partycję tabele razem w celu łatwego wykonywania zapytań. Oczywiście „raz w miesiącu” i „starsze niż 2 lata” powinny być zdefiniowane przez Ciebie na podstawie tego, co ma sens w Twoim przypadku użycia.

Dan Bechard
źródło
14
Do 10,5 miliarda, wciąż dusi. Po prostu nie próbuj wykonywać COUNT (). ;)
Dan Bechard
6
Minął rok, mamy 16,5 miliarda wierszy. Właśnie dodaliśmy dodatkowe źródło danych, więc teraz rośnie trochę szybciej. Przenieśliśmy również tę bazę danych do jej własnej instancji SQL, aby umożliwić nam dedykowanie pamięci bez głodzenia innych baz danych na serwerze. Nadal jestem w stanie sporządzić wykres dowolnego punktu danych w dowolnym 24-godzinnym okresie w ciągu ostatnich 3 lat w mniej niż sekundę. Nasi analitycy to uwielbiają.
Dan Bechard,
Wiem, że minęło trochę czasu, ale czy możesz mi powiedzieć, na jakim sprzęcie używasz tej bazy danych? Bardzo ciekawe, ponieważ mamy tabelę składającą się z 5 miliardów wierszy, rosnących o 1 miliard rocznie, a ik chciałby się dowiedzieć, czy w przyszłości
zacznie to stanowić problem
3
@ Jeroen1984 To maszyna wirtualna działająca na hoście Hyper-V ProLiant DL360e Gen8 z dwoma procesorami Intel (R) Xeon (R) CPU E5-2430. Maszyna wirtualna ma 38 GB statycznie przydzielonej pamięci RAM i pewną liczbę wirtualnych procesorów, których nie pamiętam.
Dan Bechard
19

Nie znam limitu wierszy, ale znam tabele z ponad 170 milionami wierszy. Można to przyspieszyć, używając tabel partycjonowanych (2005+) lub widoków, które łączą wiele tabel.

Sascha
źródło
19

Nie znam konkretnie MSSQL, ale 36 milionów wierszy to niewiele dla korporacyjnej bazy danych - pracując z bazami danych mainframe, 100 000 wierszy brzmi dla mnie jak tabela konfiguracji :-).

Chociaż nie jestem wielkim fanem niektórych programów Microsoftu, to nie jest Access, o którym tutaj mówimy: zakładam, że poradzą sobie one z dość dużymi rozmiarami baz danych dzięki ich korporacyjnemu DBMS.

Podejrzewam, że dni mogły być zbyt dobrym rozwiązaniem, aby go podzielić, jeśli w ogóle wymaga podziału.

paxdiablo
źródło
5

Mamy tabele w SQL Server 2005 i 2008 z ponad 1 miliardem wierszy (30 milionów dodawanych codziennie). Nie wyobrażam sobie schodzenia do gniazda szczurów i dzielenia tego na nowy stół każdego dnia.

Dużo taniej jest dodać odpowiednią przestrzeń dyskową (której i tak potrzebujesz) i pamięć RAM.

Nie ja
źródło
4

To zależy, ale powiedziałbym, że ze względu na prostotę lepiej jest trzymać wszystko w jednym stole.

100 000 rzędów dziennie to naprawdę niewiele. (W zależności od sprzętu serwera). Osobiście widziałem, jak MSSQL bez żadnych problemów obsłużył do 100 milionów wierszy w jednej tabeli. Dopóki utrzymujesz swoje indeksy w porządku, wszystko powinno być w porządku. Kluczem jest posiadanie stosów pamięci, aby indeksy nie musiały być wymieniane na dysk.

Z drugiej strony zależy to od tego, jak korzystasz z danych, jeśli potrzebujesz wykonać wiele zapytań, a jego mało prawdopodobne dane będą potrzebne, które obejmują wiele dni (więc nie będziesz musiał dołączać do tabel) szybciej, aby podzielić go na wiele tabel. Jest to często używane w zastosowaniach, takich jak sterowanie procesami przemysłowymi, w których można odczytywać wartość, powiedzmy, 50 000 instrumentów co 10 sekund. W tym przypadku szybkość jest niezwykle ważna, ale prostota nie.

Nathan
źródło
3

Raz przepełniliśmy klucz podstawowy będący liczbą całkowitą (czyli ~ 2,4 miliarda wierszy) w tabeli. Jeśli istnieje limit wierszy, prawdopodobnie nigdy nie osiągniesz go przy zaledwie 36 milionach wierszy rocznie.

znak
źródło
2

Tabelę można zapełniać, dopóki nie będzie wystarczającej ilości miejsca na dysku. Aby uzyskać lepszą wydajność, możesz spróbować przeprowadzić migrację do SQL Server 2005, a następnie podzielić tabelę na partycje i umieścić części na różnych dyskach (jeśli masz konfigurację RAID, która może Ci naprawdę pomóc). Partycjonowanie jest możliwe tylko w wersji Enterprise SQL Server 2005. Przykład partycjonowania można obejrzeć pod tym linkiem: http://technet.microsoft.com/en-us/magazine/cc162478.aspx

Możesz także spróbować stworzyć widoki dla najczęściej używanych fragmentów danych, co też jest jednym z rozwiązań.

Mam nadzieję, że to pomogło ...


źródło
0

Największa tabela, jaką napotkałem w SQL Server 8 w systemie Windows2003, miała 799 milionów z 5 kolumnami. Ale to, czy jest to dobra wola, należy mierzyć w odniesieniu do umowy SLA i przypadku użycia - np. Załaduj 50-100 000 000 rekordów i sprawdź, czy nadal działa.

buckaroo1177125
źródło
2
Nie jestem pewien, czy to w ogóle jest odpowiedź.
Andrew Barber,
-1
SELECT Top 1 sysobjects.[name], max(sysindexes.[rows]) AS TableRows, 
  CAST( 
    CASE max(sysindexes.[rows]) 
      WHEN 0 THEN -0 
      ELSE LOG10(max(sysindexes.[rows])) 
    END 
    AS NUMERIC(5,2)) 
  AS L10_TableRows 
FROM sysindexes INNER JOIN sysobjects ON sysindexes.[id] = sysobjects.[id] 
WHERE sysobjects.xtype = 'U' 
GROUP BY sysobjects.[name] 
ORDER BY max(rows) DESC
ravi
źródło
Uruchomiłem to zapytanie i otrzymałem ten wynik. Mam tabelę UrlCategories w mojej bazie danych. Więc co oznacza ten wynik? Nazwa TableRows L10_TableRows UrlKategorie 7 0,85
Aditya Bokade
-4

Podziel tabelę na partycje co miesiąc. Jest to najlepszy sposób obsługi tabel z dużym dziennym napływem, czy to Oracle, czy MSSQL.

Sameer
źródło
4
Nie wiem, jak to jest odpowiedź na zadane pytanie.
Andrew Barber,