Jakie są charakterystyki wydajności sqlite z bardzo dużymi plikami baz danych? [zamknięte]

zamknięte . To pytanie jest oparte na opinii . Obecnie nie przyjmuje odpowiedzi.

chcesz poprawić to pytanie? Zaktualizuj pytanie, aby mogło być odpowiedź z faktami i cytatami przez edytując ten post .

Zamknięte 7 lat temu .

Popraw to pytanie

2020 update , około 11 lat po opublikowaniu pytania, a później zamknięte, uniemożliwiając nowsze odpowiedzi.

Prawie wszystko tu napisane jest przestarzałe. Raz kiedyś sqlite był ograniczony do pojemności pamięci lub do 2 GB pamięci (32 bity) lub innych popularnych numerów... to było dawno temu.

Oficjalne ograniczenia są wymienione tutaj. Praktycznie sqlite może działać tak długo, jak długo jest dostępna pamięć masowa. Działa dobrze z zestawem danych większym niż pamięć, został pierwotnie stworzony, gdy pamięć była cienka i był to bardzo ważny punkt od początku.

Nie ma absolutnie żadnego problemu z przechowywaniem 100 GB data. Prawdopodobnie może przechowywać TB dobrze, ale w końcu to jest punkt, w którym trzeba zadać pytanie, czy SQLite jest najlepszym narzędziem do pracy i prawdopodobnie chcesz funkcje z pełnoprawnej bazy danych (zdalnych klientów, jednoczesnych zapisów, tylko do odczytu repliki, sharding, itp...).


Oryginalny:

Wiem, że sqlite nie działa dobrze z bardzo dużymi plikami baz danych, nawet jeśli są one obsługiwane (kiedyś na stronie sqlite był komentarz stwierdzający, że jeśli potrzebujesz plików o rozmiarze powyżej 1 GB możesz rozważyć użycie enterprise RDBMS. Nie mogę go już Znaleźć, może być związane ze starszą wersją sqlite).

Jednak, dla moich celów chciałbym dowiedzieć się, jak źle jest naprawdę, zanim rozważę inne rozwiązania.

Mówię o plikach danych SQLite w zakresie multi-gigabajtów, począwszy od 2GB. Ktoś ma z tym jakieś doświadczenie? Jakieś wskazówki/pomysły?

Author: user5994461, 2009-04-24

9 answers

Więc zrobiłem kilka testów z sqlite dla bardzo dużych plików i doszedłem do pewnych wniosków (przynajmniej dla mojej konkretnej aplikacji).

Testy obejmują pojedynczy plik sqlite z pojedynczą tabelą lub wieloma tabelami. Każda tabela miała około 8 kolumn, prawie wszystkie liczby całkowite i 4 indeksy.

Chodziło o to, aby wstawić wystarczającą ilość danych, aż pliki sqlite będą miały około 50GB.

Single Table

Próbowałem wstawić wiele wierszy do pliku sqlite z tylko jedną tabelą. Gdy plik miał około 7GB (niestety nie mogę być konkretny co do liczby wierszy) wstawianie trwało zbyt długo. Oszacowałem, że mój test Wstawienia wszystkich moich danych zajmie około 24 godzin, ale nie zakończył się nawet po 48 godzinach.

To prowadzi mnie do wniosku, że pojedyncza, bardzo duża tabela sqlite będzie miała problemy z wstawianiem i prawdopodobnie również innymi operacjami.

Myślę, że nie jest to zaskoczeniem, ponieważ tabela staje się większa, wstawianie i aktualizowanie wszystkich indeksów trwa dłużej.

Wiele Tabel

Następnie próbowałem podzielić dane według czasu na kilka tabel, jedna tabela dziennie. Dane dla oryginalnej tabeli 1 zostały podzielone na ~700 tabel.

Ta konfiguracja nie miała problemów z wstawianiem, nie trwało to dłużej w miarę postępu czasu, ponieważ nowa tabela była tworzona dla każdego dnia.

Problemy Z Próżnią

Jak wskazuje i_like_caffeine, polecenie VACUUM jest problemem im większy jest plik SQLITE. Jako więcej wstawianie/usuwanie odbywa się, fragmentacja pliku na dysku będzie się pogarszać, więc celem jest okresowe odkurzanie w celu optymalizacji pliku i odzyskania miejsca na pliku.

Jednak, jak wskazuje dokumentacja , pełna kopia bazy danych jest wykonywana w celu wykonania próżni, co zajmuje bardzo dużo czasu. Im mniejsza baza danych, tym szybciej zakończy się Ta operacja.

Wnioski

Dla mojej konkretnej aplikacji, prawdopodobnie będę dzielił dane ponad kilka plików db, jeden dziennie, aby uzyskać najlepszą wydajność próżni i szybkość wstawiania/usuwania.

To komplikuje zapytania, ale dla mnie warto wymienić możliwość indeksowania tak dużej ilości danych. Dodatkową zaletą jest to, że mogę po prostu usunąć cały plik db, aby zrzucić dane o wartości jednego dnia (wspólna operacja dla mojej aplikacji).

Prawdopodobnie będę musiał również monitorować rozmiar tabeli na plik, aby zobaczyć, kiedy prędkość stanie się problemem.

Szkoda, że nie istnieje metoda próżni przyrostowej inna niż auto vacuum . Nie mogę go użyć, ponieważ moim celem dla próżni jest defragmentacja pliku (przestrzeń plików nie jest wielka sprawa), czego auto vacuum nie robi. W rzeczywistości dokumentacja stwierdza, że może to pogorszyć fragmentację, więc muszę okresowo wykonywać pełną próżnię na pliku.

 250
Author: Snazzer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-01 15:25:32

Używamy DBS 50 GB+ na naszej platformie. no complains działa świetnie. Upewnij się, że robisz wszystko dobrze! Używasz predefiniowanych instrukcji ? *SQLITE 3.7.3

  1. transakcje
  2. wstępnie złożone oświadczenia
  3. Zastosuj te ustawienia (zaraz po utworzeniu DB)

    PRAGMA main.page_size = 4096;
    PRAGMA main.cache_size=10000;
    PRAGMA main.locking_mode=EXCLUSIVE;
    PRAGMA main.synchronous=NORMAL;
    PRAGMA main.journal_mode=WAL;
    PRAGMA main.cache_size=5000;
    

Mam nadzieję, że to pomoże innym, działa świetnie tutaj

 174
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-30 17:10:07

Stworzyłem bazy danych SQLite o rozmiarze do 3,5 GB bez zauważalnych problemów z wydajnością. Jeśli dobrze pamiętam, myślę, że SQLite2 może mieć jakieś niższe limity, ale nie sądzę, że SQLite3 ma takie problemy.

Zgodnie ze stroną SQLite Limits , Maksymalny rozmiar każdej strony bazy danych wynosi 32K. a maksymalna liczba stron w bazie danych to 1024^3. Według mojej matematyki to 32 terabajty jako maksymalny rozmiar. Myślę, że przekroczysz limity swojego systemu plików zanim uderzam w SQLite ' a!

 66
Author: Paul Lefebvre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-24 14:46:10

Wiele z powodów, dla których wykonanie wstawek zajęło > 48 godzin, wynika z Twoich indeksów. Jest niesamowicie szybszy:

1-upuść wszystkie indeksy 2-Czy wszystkie wkładki 3-Utwórz ponownie indeksy

 57
Author: user352992,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-28 14:22:47

Oprócz zwykłej rekomendacji:

  1. indeks upuszczania dla wkładki zbiorczej.
  2. wsadowe wstawianie / aktualizacje w dużych transakcjach.
  3. Tune your buffer cache / disable journal / w PRAGMAs.
  4. Użyj 64-bitowej maszyny(aby móc korzystać z dużej ilości pamięci podręcznej™).
  5. [dodano lipiec 2014] użyj common table expression (CTE) zamiast uruchamiania wielu zapytań SQL! Wymaga wydania SQLite 3.8.3.

Z moich doświadczeń z SQLite3:

  1. dla maksymalnej prędkości wstawiania, nie używaj schematu z żadnym ograniczeniem kolumn. (zmiana tabeli później w razie potrzeby nie można dodawać ograniczeń za pomocą zmiany tabeli).
  2. zoptymalizuj swój schemat, aby przechowywać to, czego potrzebujesz. Czasami oznacza to rozbicie tabel i / lub nawet kompresję / przekształcenie danych przed włożeniem ich do bazy danych. Świetnym przykładem jest przechowywanie adresów IP jako (długich) liczb całkowitych.
  3. jedna tabela na plik db - aby zminimalizować spór o blokadę. (Użycie załącz bazę danych jeśli chcesz mieć pojedynczy obiekt połączenia.
  4. SQLite może przechowywać różne typy danych w tej samej kolumnie( dynamiczne pisanie), użyj tego na swoją korzyść.

Pytanie/komentarz mile widziany. ;-)

 35
Author: Lester Cheung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-25 14:52:09

Mam bazę danych SQLite 7GB. Wykonanie konkretnego zapytania z łączeniem wewnętrznym zajmuje 2,6 s Aby to przyspieszyć, próbowałem dodać indeksy. W zależności od tego, który indeks(y) dodałem, czasami zapytanie spadło do 0.1 s, a czasami wzrosło do 7s. Myślę, że problem w moim przypadku polegał na tym, że jeśli kolumna jest wysoce duplikowana, to dodanie indeksu obniża wydajność : (

 10
Author: Mike Oxynormas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-15 08:29:22

Myślę, że główne skargi na skalowanie sqlite to:

  1. zapis pojedynczego procesu.
  2. Nie ma lustrzanego odbicia. Brak replikacji.
 9
Author: Unknown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-24 01:29:36

W dokumentacji SQLite było kiedyś stwierdzenie, że praktyczny limit rozmiaru pliku bazy danych wynosił kilkadziesiąt GB: s. wynikało to głównie z potrzeby, aby SQLite "przydzielił bitmapę brudnych stron", gdy rozpoczynasz transakcję. Tak więc dla każdego MB w bazie danych wymagane było 256 bajtów pamięci RAM. Wstawianie do pliku DB o pojemności 50 GB wymagałoby dużej (2^8)*(2^10)=2^18=256 MB PAMIĘCI RAM.

Ale od najnowszych wersji SQLite, to nie jest już potrzebne. Czytaj więcej TUTAJ .

 9
Author: Alix Axel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-13 13:00:33

Miałem problemy z dużymi plikami sqlite podczas używania polecenia vacuum.

Nie próbowałem jeszcze funkcji auto_vacuum. Jeśli spodziewasz się często aktualizować i usuwać dane, warto na to spojrzeć.

 8
Author: eodonohoe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-30 20:12:13