Kompresja zajmowanego miejsca na dysku przez tabelę i indeksy

Kompresja zajmowanego miejsca na dysku przez tabelę i indeksy
JA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3
0

Tworzę ostatnio tabelę, która jest połączeniem wybranych kolumn z dwóch ogromnych tabel (po ok 30 mld rekordów każda).
Jedna z nich, ważniejsza waży 1.7 TB, a druga, która ma rozszerzać część informacji waży 1TB. Zawierają one dane od 2014 roku.
Do tej pory do nowej tabeli przeniosłem dane od 2023 roku do dnia dzisiejszego i już zauważyłem, że moja nowa tabela waży 4TB, i zawiera ona 12mld rekordów (czyli gdzieś mniej więcej 1/3 całości).
Po doczytaniu literatury założyłem na tabeli klastrowany indeks kolumnowy oraz popartycjonowałem dane po dacie, po przedziałach 1 miesiąca - to daje jakieś 500 mln rekordów na partycje. Dodatkowo dane są kompresowane po "row" i po "page". Po wszystkich tych zabiegach moja tabela waży obecnie 1.8TB co jest i tak matematycznie za dużo względem jej poprzedników. Dodatkowo, chciałem do lepszego funkcjonowania tabeli założyć jeszcze dodatkowo indeksy, ale zauważyłem, że już przy trzech prostych indeksach ich rozmiar wynosi łącznie 2TB - nie optymalizowałem ich jeszcze za bardzo pod tym kątem.
Jakie kroki przy tworzeniu takiej tabeli i nowych indeksów powinienem podjąć, albo które zrobić inaczej? Z różnic które dostrzegłem między tymi nową, a starymi tabelami to to, że dane są w poprzednich partycjonowane po 1 dzień czyli po około 17 mln rekordów. Nowa tabela posiada raczej mało wartości NULL i ma około 30 kolumn.

Z góry dziękuję za jakieś rady

SL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1133
0

Na sam początek opisz jak chcesz używać tej bazy https://aws.amazon.com/compare/the-difference-between-olap-and-oltp/

Ogarnij też ile dokładnie zajmują dane jak i indeksy https://stackoverflow.com/questions/781873/how-to-figure-out-size-of-indexes-in-mysql , nie ma sensu zgadywanie, gdy możesz tą informację po prostu wyciągnąć

Odpal też https://dev.mysql.com/doc/refman/8.4/en/optimize-table.html dla pewności, że nie masz żadnych śmieci, które można wyczyścić

JA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3
0

Baza ma być OLAPowa. Dane będą zaczytywane raz dziennie (około 20 mln rekordów). Do większości zapytań wystarczą mi zwykłe indeksy, jednak dla jednego konkretnego zastosowania będę potrzebować indeksu pokrywającego, żeby czas odpowiedzi sprowadzić do 2 sekund, a nie 45 jak to jest w przypadku zwykłego indeksu.
Tutaj screen co ile miejsca zajmuje. 4501, to ten indeks pokrywający. Baza sama zajmuje 1721 GB
screenshot-20250408114636.png

cepa
  • Rejestracja: dni
  • Ostatnio: dni
0

A co konkretnie chcesz uzyskac? Samo zmniejszenie rozmiaru danych na dysku czy jakiś wzrost wydajności?

Generalnei 2..4TB bazy danych raczej nie trzymasz na "normalnym" komputerze. Jeżeli jest to bardziej serewerowe środowisko to możesz skompresować całą bazę na poziomie systemu plikow np ZFS, który ma kompresje LZ4 a przy okazji snapshoty. Do tego jeżeli masz przeczesywać te indeksy to przy takim rozmiarze bazy i tak jesteś skazany na trzymanie jej na dyskach NVMe. Dzięki kompresji na poziomie systemu plików dostajesz zysk wydajności bo przykładowo transfer danych z dysku na NVMe to 2GB/s a z kompresja masz większą "gęstość" danych co daje wzrost wydajności IO.

Mam takie doświadczenia z bazą danych OpenStreetMap (planeta), po kompresji jakies 600GB, bez 1.3TB, PostgreSQL / PostGIS.

grinder
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 18
0
  1. Skoro danych jest więcej niż w tabelach źródłowych i jest to "matematycznie nieprawidłowe", to powodem może być że nie jest to relacja 1:1 jakby można wnioskować z opisu, i część danych jest duplikowana? -> sprawdzić poprawność złączenia danych
  2. Dane siedzą już w 2 tabelach - to może zamiast wrzucać je do 3 tabeli wystarczył by jakiś widok?
  3. Zmiana sposobu partycjonowania nie wpływa drastycznie na rozmiar tabel
  4. Kompresja bardzo zależy od typu użytych danych. Być może trzeba wprowadzić jakieś konwersje (w miarę możliwości ) np char(n) -> nvarchar(n), nvarchar(max) ->nvarchar(n)
  5. Indeksy także należało by skompresować
  6. Dużo danych i szybko - > sorry, fizyki nie oszukasz. Należało by zapoznać się z rozwiązaniami pokroju SupremeRAID SR-1010 i tym podobne
  7. Kompresja w ms sql server nie jest rewelacyjna pod względem oszczędności danych, ze względu na położenie nacisku na ograniczenie zasobów potrzebnych na kompresje/dekompresje danych w locie. Jeżeli ważniejsza jest wielkość plików na dysku, być może wybór kompresji na poziomie systemu plików może być lepszą opcją.
JA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3
0

Jasne, dzięki za rady pokombinuję i postaram się znaleźć najlepszą opcję dla siebie 😀

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.