Mam aplikację, która używa GUID jako klucza podstawowego w prawie wszystkich tabelach i przeczytałem, że istnieją problemy z wydajnością podczas używania GUID jako klucza podstawowego. Szczerze mówiąc, nie widziałem żadnego problemu, ale mam zamiar uruchomić nową aplikację i nadal chcę używać identyfikatorów GUID jako kluczy podstawowych, ale myślałem o użyciu kompozytowego klucza podstawowego (GUID i może innego pola .)
Korzystam z GUID, ponieważ są one ładne i łatwe w zarządzaniu, gdy masz różne środowiska, takie jak bazy danych „produkcyjne”, „testowe” i „programistyczne”, a także do migracji danych między bazami danych.
Będę korzystał z Entity Framework 4.3 i chcę przypisać Guid do kodu aplikacji, przed wstawieniem go do bazy danych. (tzn. nie chcę, aby SQL generował Guid).
Jaka jest najlepsza praktyka tworzenia kluczy podstawowych opartych na GUID, aby uniknąć przypuszczalnych spadków wydajności związanych z tym podejściem?
Odpowiedzi:
Identyfikatory GUID mogą wydawać się naturalnym wyborem dla twojego klucza podstawowego - a jeśli naprawdę musisz, prawdopodobnie możesz argumentować, aby użyć go dla KLUCZA PODSTAWOWEGO tabeli. Zdecydowanie odradzam korzystanie z kolumny GUID jako klucza klastrowania , co SQL Server domyślnie robi, chyba że wyraźnie powiesz, żeby tego nie robił .
Naprawdę musisz rozdzielić dwa problemy:
klucz podstawowy jest logiczną konstrukcją - jeden z kluczy kandydujących, który jednoznacznie identyfikuje i niezawodnie każdego wiersza w tabeli. To może być cokolwiek, naprawdę - W
INT
, AGUID
, łańcuch - wybrać to, co sprawia, że największy sens dla scenariusza.klucz klastrów (kolumna lub kolumn, które definiują „klastrowego indeksu” na stole) - jest to fizyczne rzeczy związane z magazynowaniem, a tu, mały, stabilny, coraz większa typ danych jest najlepszym pick -
INT
alboBIGINT
jako swój Domyślna opcja.Domyślnie klucz podstawowy w tabeli programu SQL Server jest również używany jako klucz klastrowania - ale nie musi tak być! Osobiście widziałem ogromny wzrost wydajności, gdy dzielę poprzedni klucz podstawowy / klastrowany oparty na GUID na dwa osobne klucze - klucz podstawowy (logiczny) na GUID i klucz grupowania (porządkowania) w osobnej
INT IDENTITY(1,1)
kolumnie.Jak Kimberly Tripp - Królowa Indeksowania - i inni wspominali wiele razy -
GUID
klucz klastrowania nie jest optymalny, ponieważ ze względu na jego losowość doprowadzi do ogromnej fragmentacji stron i indeksów oraz ogólnie złej wydajności.Tak, wiem - jest
newsequentialid()
w SQL Server 2005 i nowszych - ale nawet to nie jest w pełni i całkowicie sekwencyjne, a zatem cierpi z powodu tych samych problemów coGUID
- tylko trochę mniej wyraźnie.Jest jeszcze jeden problem do rozważenia: klucz klastrowania w tabeli zostanie dodany do każdego wpisu w każdym indeksie nieklastrowanym w tabeli - dlatego naprawdę chcesz mieć pewność, że jest tak mały, jak to możliwe. Zazwyczaj
INT
ponad 2 miliardy wierszy powinno wystarczyć do przeważającej większości tabel - w porównaniu zGUID
kluczem klastrowym możesz zaoszczędzić sobie setki megabajtów pamięci na dysku i w pamięci serwera.Szybkie obliczenia - użycie
INT
vs.GUID
jako klucza podstawowego i klucza grupowania:RAZEM: 25 MB vs. 106 MB - i to tylko na jednym stole!
Więcej jedzenia do przemyślenia - doskonałe rzeczy Kimberly Tripp - przeczytaj, przeczytaj jeszcze raz, przetrawiaj! To naprawdę ewangelia indeksowania SQL Server.
PS: oczywiście, jeśli masz do czynienia z zaledwie kilkuset lub kilkoma tysiącami wierszy - większość z tych argumentów tak naprawdę nie będzie miała na ciebie większego wpływu. Jednak: jeśli wejdziesz w dziesiątki lub setki tysięcy wierszy lub zaczniesz liczyć w milionach - wtedy punkty te staną się bardzo ważne i bardzo ważne do zrozumienia.
Aktualizacja: jeśli chcesz mieć
PKGUID
kolumnę jako klucz podstawowy (ale nie klucz klastrowania), a kolejną kolumnęMYINT
(INT IDENTITY
) jako klucz klastrowania - użyj tego:Zasadniczo: musisz tylko wyraźnie powiedzieć
PRIMARY KEY
, że jest to ograniczenieNONCLUSTERED
(w przeciwnym razie domyślnie jest on tworzony jako indeks klastrowany) - a następnie tworzysz drugi indeks, który jest zdefiniowany jakoCLUSTERED
To zadziała - i jest to poprawna opcja, jeśli masz istniejący system, który musi zostać „przeprojektowany” pod kątem wydajności. W przypadku nowego systemu, jeśli zaczynasz od zera i nie jesteś w scenariuszu replikacji, to zawsze wybrałbym
ID INT IDENTITY(1,1)
jako mój klastrowany klucz podstawowy - znacznie bardziej wydajny niż cokolwiek innego!źródło
DATETIME
na przykład NIE są przydatne dla klucza klastrowania, ponieważ mają one jedynie dokładność 3,33 ms, a zatem mogą istnieć duplikaty. Więc w takim przypadku * nadal potrzebujeszINT IDENTITY
zamiast tego - dlatego zwykle używam tego domyślnie, ponieważ z mojego ponad 20-letniego doświadczenia naprawdę przydatny naturalny klucz prawie nigdy nie istnieje naprawdę ...Używam GUID jako PK od 2005 roku. W tym świecie rozproszonych baz danych jest to absolutnie najlepszy sposób łączenia rozproszonych danych. Możesz uruchamiać i zapominać o scalaniu tabel bez martwienia się o dopasowanie ints do połączonych tabel. Połączenia GUID można bez obaw kopiować.
Oto moja konfiguracja używania identyfikatorów GUID:
PK = GUID. Identyfikatory GUID są indeksowane podobnie jak ciągi, więc tabele wysokich wierszy (ponad 50 milionów rekordów) mogą wymagać partycjonowania tabel lub innych technik wydajności. SQL Server staje się niezwykle wydajny, więc problemy z wydajnością mają coraz mniejsze zastosowanie.
PK Guid jest indeksem nieklastrowanym. Nigdy nie klastruj indeksu GUID, chyba że jest to NewSequentialID. Ale nawet wtedy restart serwera spowoduje poważne przerwy w składaniu zamówień.
Dodaj ClusterID Int do każdej tabeli. To jest twój CLUSTERED Index ... który porządkuje twój stół.
Dołączanie do ClusterIDs (int) jest bardziej wydajne, ale pracuję z 20-30 milionami tabel rekordów, więc dołączanie GUID nie ma widocznego wpływu na wydajność. Jeśli chcesz uzyskać maksymalną wydajność, użyj koncepcji ClusterID jako klucza podstawowego i dołącz do ClusterID.
Oto moja tabela e-mail ...
źródło
Obecnie tworzę aplikację internetową z EF Core i oto wzór, którego używam:
Wszystkie moje zajęcia (tabele) oraz int PK i FK. Mam dodatkową kolumnę z typem Guid (generowanym przez konstruktor c #) z indeksem nieklastrowanym.
Wszystkimi połączeniami tabeli w EF zarządza się za pomocą kluczy int, podczas gdy cały dostęp z zewnątrz (kontrolery) odbywa się za pomocą prowadnic.
To rozwiązanie pozwala nie wyświetlać kluczy int na adresach URL, ale pozwala zachować porządek i szybkość modelu.
źródło
Jeśli używasz GUID jako klucza podstawowego i tworzysz klastrowany indeks, sugeruję użyć dla niego domyślnej wartości NEWSEQUENTIALID ()
źródło
Ten link mówi to lepiej niż mogłem i pomógł mi w podejmowaniu decyzji. Zwykle wybieram int jako klucz podstawowy, chyba że mam określoną potrzebę, a także pozwalam serwerowi SQL na automatyczne generowanie / obsługę tego pola, chyba że mam konkretny powód, aby tego nie robić. W rzeczywistości problemy z wydajnością należy ustalić na podstawie konkretnej aplikacji. W grę wchodzi wiele czynników, w tym między innymi oczekiwany rozmiar bazy danych, prawidłowe indeksowanie, wydajne zapytania i inne. Chociaż ludzie mogą się nie zgadzać, myślę, że w wielu scenariuszach nie zauważysz różnicy w żadnej z tych opcji i powinieneś wybrać to, co jest bardziej odpowiednie dla Twojej aplikacji, a co pozwala na łatwiejsze, szybsze i bardziej efektywne tworzenie (Jeśli nigdy nie ukończysz aplikacji jaką różnicę robi reszta :).
https://web.archive.org/web/20120812080710/http://databases.aspfaq.com/database/what-should-i-choose-for-my-primary-key.html
PS Nie jestem pewien, dlaczego miałbyś skorzystać z Composite PK ani jakie korzyści, które według ciebie by to dały.
źródło
W większości przypadków nie należy go używać jako klucza podstawowego tabeli, ponieważ naprawdę wpływa to na wydajność bazy danych. przydatne linki dotyczące wpływu GUID na wydajność i jako klucz podstawowy.
źródło
Posiadanie identyfikatora sekwencyjnego znacznie ułatwia hakerowi lub eksploratorowi danych złamanie zabezpieczeń witryny i danych. Należy o tym pamiętać przy wyborze PK dla strony internetowej.
źródło