Mam już kilka milionów wierszy w mojej bazie danych. Nie wiedziałem o typie danych UUID PostgreSQL podczas projektowania mojego schematu.
Jedna z tabel ma 16 mln wierszy (około 3,5 mln do 4 mln rekordów na odłamek), rosnąc przy około 500 000 rekordów dziennie. Nadal mam luksus wyłączania systemu produkcyjnego na kilka godzin w razie potrzeby. Nie będę miał tego luksusu za tydzień lub dwa.
Moje pytanie brzmi: czy warto to zrobić? Zastanawiam się nad wydajnością JOIN, wykorzystaniem miejsca na dysku (pełny zrzut gzip'd to 1,25 GiB), tego typu rzeczy.
Schemat tabeli to:
# \d twitter_interactions
Table "public.twitter_interactions"
Column | Type | Modifiers
-------------------------+-----------------------------+-----------
interaction_id | character(36) | not null
status_text | character varying(1024) | not null
screen_name | character varying(40) | not null
twitter_user_id | bigint |
replying_to_screen_name | character varying(40) |
source | character varying(240) | not null
tweet_id | bigint | not null
created_at | timestamp without time zone | not null
Indexes:
"twitter_interactions_pkey" PRIMARY KEY, btree (interaction_id)
"twitter_interactions_tweet_id_key" UNIQUE, btree (tweet_id)
"index_twitter_interactions_on_created_at" btree (created_at)
"index_twitter_interactions_on_screen_name" btree (screen_name)
Triggers:
insert_twitter_interactions_trigger BEFORE INSERT ON twitter_interactions FOR EACH ROW EXECUTE PROCEDURE twitter_interactions_insert_trigger()
Number of child tables: 9 (Use \d+ to list them.)
źródło
Nie jestem postgresową postacią wyobraźni, ale w oparciu o to, co wiem z SQL Server, im więcej wierszy możesz zmieścić na stronie danych, tym lepsza wydajność będziesz mieć (odczyt danych z dysku jest zwykle najdroższa operacja). Tak więc, idąc od 36 owski 1 bajt szerokim zakresie do 16 bajtów GUID wydaje się proste oszczędności. Im mniej odczytów możesz ponieść, tym szybciej możesz zwrócić wyniki. Wszystko to oczywiście zakłada, że GUID / UUID spełnia potrzeby biznesowe tabeli. Jeśli UUID to spełni, czy bigint ? To jeszcze bardziej zmniejszy koszty przechowywania o kolejne 8 bajtów na wiersz.
Edytuj 1
Dane postaci w Postgres wiążą się z dodatkowymi kosztami przechowywania. Krótkie ciągi, poniżej 127 bajtów, mają narzut 1 bajt, podczas gdy cokolwiek dłuższego ma 4 bajty, tak więc drugi respondent wymyślił koszt 40 bajtów dla pola 36 bajtów. Ale jest też opcja kompresji ciągów, więc być może nie będzie to kosztować pełnych 40. Nie mogę powiedzieć, jaki byłby ostateczny koszt, ale fundamenty pozostają: wszystko, co przekracza 16 bajtów, zwiększy koszt pamięci, odczytywanie jej dłużej i zużywają więcej pamięci.
źródło
Oprócz problemu z przestrzenią pamiętaj, że musisz zmienić każdą tabelę, aby użyć poprawnego typu danych, w przeciwnym razie wydajność łączenia znacznie spadnie.
źródło
Oprócz oszczędności wielkości danych i indeksów (jak powiedzieli inni), co przekłada się na oszczędności we / wy, należy wziąć pod uwagę, w jaki sposób wygenerować nowe wartości
interaction_id
i jaki będzie wpływ na indeksy i warunki zapytania (złączenia).W przypadku indeksu - będzie mniejszy, jednak jeśli wiele zapytań korzysta ze skanów indeksów, przejście na UUID może uniemożliwić skanowanie indeksów (w zależności od sposobu generowania UUID) i
bigint
może być znacznie lepszym wyborem.Wreszcie, ponieważ faktyczny wpływ na wydajność zależy również od wzorców użytkowania i dystrybucji danych, należy uruchomić testy i mieć środowisko programistyczne i testowe, w którym można przetestować zmiany.
To da ci znacznie dokładniejszą odpowiedź na temat wpływu na wydajność.
źródło