Jestem po pewnym potwierdzeniu tego pomysłu naprawienia źle działającej bazy danych lub lepszej sugestii, jeśli ktoś ją posiada. Zawsze otwarci na lepsze sugestie.
Mam bardzo dużą bazę danych (ponad 20 milionów rekordów rosnących o około 1/2 miliona dziennie), które używają GUID jako PK.
Niedopatrzenie z mojej strony, ale PK jest zgrupowane na serwerze SQL i powoduje problemy z wydajnością.
Powód przewodnika - ta baza danych jest częściowo zsynchronizowana ze 150 innymi bazami danych, więc PK musiał być unikalny. Synchronizacja nie jest zarządzana przez SQL Server, ale jest zbudowany niestandardowy proces, który utrzymuje dane w synchronizacji dla wymagań systemu - wszystko na podstawie tego identyfikatora GUID.
Każda ze 150 zdalnych baz danych nie przechowuje pełnych danych przechowywanych w centralnej bazie danych SQL. przechowują tylko podzbiór danych, których faktycznie potrzebują, a wymagane dane nie są dla nich unikalne (10 ze 150 baz danych może mieć na przykład niektóre te same rekordy z baz danych innych witryn - współużytkują). Ponadto - dane są generowane w odległych lokalizacjach - nie w centralnym punkcie - stąd potrzeba GUID.
Centralna baza danych służy nie tylko do synchronizacji wszystkiego, ale zapytania od ponad 3000 użytkowników będą wykonywane względem tej bardzo dużej pofragmentowanej bazy danych. Jest to już duży problem w początkowych testach.
Na szczęście nie jesteśmy jeszcze na żywo - więc mogę wprowadzać zmiany i przestawiać je w razie potrzeby w trybie offline, co jest przynajmniej czymś.
Wydajność zdalnych baz danych nie stanowi problemu - podzbiory danych są dość małe, a baza danych zwykle nigdy nie przekracza łącznie 1 GB. Rekordy są dość regularnie przekazywane do głównego systemu i usuwane z mniejszych płyt BD, gdy nie są już potrzebne.
Wydajność centralnej bazy danych, która przechowuje wszystkie rekordy, jest żałosna - ze względu na klastrowy identyfikator GUID jako klucz podstawowy dla tak wielu rekordów. Fragmentacja indeksu jest wyłączona z wykresów.
Tak więc - myślami, aby rozwiązać problem z wydajnością, należy utworzyć nową kolumnę - Nie podpisano BIGINT TOŻSAMOŚĆ (1,1), a następnie zmienić klastrowane PK tabeli BIGINT kolumny.
Utworzyłbym unikalny indeks nieklastrowany w polu GUID, który był kluczem podstawowym.
Mniejsze zdalne 150 baz danych nie musi wiedzieć o nowej PK w bazie danych Central SQL Server - będzie ona służyć wyłącznie do organizowania danych w bazie danych i zatrzymania złej wydajności i fragmentacji.
Czy to zadziała i poprawi wydajność centralnej bazy danych SQL i zapobiegnie przyszłej fragmentacji indeksu (do pewnego stopnia)? czy może przegapiłem tutaj coś bardzo ważnego, co podskoczy i ugryzie mnie i spowoduje jeszcze większy smutek?
źródło
int
za 4255 dni (11,5 lat). Gdyby to zrobił,Odpowiedzi:
Z pewnością NIE musisz klastrować na GUID. Jeśli masz coś, co pozwoliłoby ci jednoznacznie zidentyfikować rekordy inne niż ten GUID, sugeruję, abyś spojrzał na zbudowanie unikalnego indeksu na tym innym polu i utworzenie tego indeksu w klastrze. Jeśli nie, możesz klastrować na innych polach, nawet przy użyciu nietypowych indeksów. Takie podejście polegałoby na klastrze, jednak najlepiej ułatwia dzielenie danych i wysyłanie zapytań - jeśli więc masz pole „region” lub coś takiego, może to być kandydat do twojego schematu klastrowania.
Problemem z przejściem na a
BIGINT
byłoby dodanie danych z innych baz danych i zintegrowanie ich bazy danych z centralnym sklepem. Jeśli nie jest to rozważanie - i nigdy nie będzie rozważaniem - to tak,BIGINT
rozwiązałoby to problem przywrócenia równowagi indeksu.Za kulisami, jeśli nie określisz indeksu klastrowego, SQL Server robi to samo: tworzy pole ID wiersza i odwzorowuje w nim wszystkie inne indeksy. Tak więc, robiąc to sam, rozwiązujesz go tak, jak rozwiązałby go SQL.
źródło
To wysokie zamówienie.
Pozwól, że zasugeruję podejście środkowego człowieka.
Miałem problemy z generowaniem losowych przewodników przez System.Guid.NewGuid (). (Pozwoliłem klientowi na utworzenie własnego identyfikatora GUID, zamiast polegać na bazie danych, aby utworzyć sekwencję).
Po przejściu do UuidCreateSequential po stronie klienta moja wydajność stała się DUŻO lepsza, szczególnie w przypadku INSERT.
Oto kod klienta DotNet voodoo. Jestem pewien, że skądś zastawiłem:
POMYSŁ ALTERNATYWNY:
Jeśli twoja główna baza danych i zdalne bazy danych są „połączone” (jak w, sp_linkserver) ...... to możesz użyć głównej bazy danych jako „generator uuid”.
Nie chcesz dostawać UUIDa „jeden po drugim”, to zbyt dużo sprytu.
Ale możesz wziąć zestaw Uuida.
Poniżej znajduje się kod:
/ *
* /
źródło
Na podstawie Twojego opisu wybierz BIGINT. Jednak indeks GUID może nie być unikalny, ponieważ GUID i tak powinny być globalnie unikalne.
źródło
Jeśli GUID jest przechowywany poprawnie jako unikatowy identyfikator, nie powinien mieć żadnych problemów z wydajnością ... a jeśli możesz użyć Sekwencyjnego GUID jeszcze lepiej ...
Również @mattytommo ma dobry punkt około 11,5 roku z użyciem INT ...
źródło