2009-10-19 12 views
20

W bazie danych, w której wszystkie klucze podstawowe są identyfikatorami GUID, jakie są różnice/implikacje i/lub plusy i minusy, używając newid() versus newsequentialid() jako "domyślnej wartości lub wiązania".newid() vs newsequentialid() Jakie są różnice/plusy i minusy?

Jedyną różnicą, o której mi wiadomo jest to, że newid() tworzy nowy przypadkowy identyfikator GUID w przeciwieństwie do newsequentialid() tworzy nowy GUID oparty na ostatnim, który jest w tabeli w sposób zwiększany.

Odpowiedz

23

Jak rozumiem, podczas wykonywania wstawki z rzędu, DB zostanie wstawione w kolejności względem innych PK w tabeli. Przy normalnym guidzie może to być dowolne miejsce na stole. Funkcja newsequentialid() będzie zawsze dodawana do końca tabeli.

Poprawiono wydajność wkładek.

This site wyjaśnia różnice i poziomy odniesienia między dwiema różnymi metodami.

Aktualizacja - przeniesiony post na blogu. Link odnosi się teraz do linku web.archive.org. Oto klucz wynos:

enter image description here

Najbardziej uderzające jest liczbą zapisów wymaganych przez funkcję systemową NEWID. To, w połączeniu ze średnią gęstością strony wynoszącą 69%, świadczy o rozdarciu strony spowodowanym przez losowy rozkład wstawek na poziomie liścia. Gdy strona wypełni się, musi zostać podzielona na 2 strony po 50% każda, aby wstawić do wypełnienia. Podział stron nie tylko spowodował słabą gęstość strony, ale bardzo źle rozłożył strony danych (99% prawdopodobieństwa, że ​​następna strona danych nie znajduje się obok aktualnej). W naszych testach najbardziej prawdopodobne miejsce dla strony wolnej wymaganej dla podziału strony znajduje się na końcu tabeli, niezależnie od tego, gdzie wstawiany jest wiersz. Dlatego aby czytać wiersze w kolejności, skan musi nadal przeskakiwać pomiędzy szeroko rozłożonymi podzielonymi stronami, stąd przerażająca fragmentacja.

--Stefan Delmarco

+0

Huh? Jeśli są generowane sekwencyjnie Jak można zagwarantować, że wygenerowany identyfikator GUID jest rzeczywiście unikatowy, zamiast być po prostu czymś, co wygląda jak identyfikator GUID? – Justin

+4

@Justing - nie ma * gwarancji *, że GUID jest wyjątkowy, jest po prostu bardzo prawdopodobne. –

+1

Linki są niestabilne ... Fotia 404s link w odpowiedzi. –

-2

wiem, NEWID() generuje GUID w kolejności losowej i NEWSEQUENTIALID() generuje GUID w kolejności. NEWSEQUENTIALID() może być użyty TYLKO w domyślnej klauzuli tabeli.

+2

Nie dodałeś niczego do tego, co zostało już napisane w pytanie. –

1

Z mojego rozumowania, po uruchomieniu instancji SQL, identyfikator GUID NEWSEQUENTIALID jest inicjowany do wartości losowej. Następnie przez cały czas działania jego identyfikatory GUID są zwiększane na centralnym identyfikatorze GUID, a nie na podstawie ostatniego identyfikatora GUID wygenerowanego dla tabeli.

+1

Korzyść z tego jest w indeksach. Kompletne losowe identyfikatory GUID fragmentują indeksy za dużo, sekwencyjne identyfikatory GUID są dobre do wstawiania i indeksowania wydajności. – Todd

+0

[Stan Microsoft] (https://msdn.microsoft.com/da-dk/library/ms189786.aspx), który jest sekwencyjny w odniesieniu do ostatniego identyfikatora GUID wygenerowanego od ostatniego uruchomienia komputera hosta. –

9

Jeśli chodzi o użycie kluczy sekwencyjnych (jak w przypadku tożsamości, sekwencji i NEWSEQUENTIALID) kontra niesekwencyjnych (jak w przypadku NEWID lub niestandardowego generatora losowych kluczy), należy wziąć pod uwagę kilka aspektów.

Począwszy od klawiszy sekwencyjnych, wszystkie wiersze przechodzą w prawy koniec indeksu. Gdy strona jest pełna, SQL Server przydziela nową stronę i wypełnia ją. Powoduje to mniejszą fragmentację indeksu, co jest korzystne dla wydajności odczytu. Ponadto insercje mogą być szybsze, gdy pojedyncza sesja ładuje dane, a dane znajdują się na jednym dysku lub niewielkiej liczbie napędów.

Jednak w przypadku podsystemów pamięci masowej o wysokim końcu, które mają wiele wrzecion, sytuacja może się różnić.Podczas ładowania danych z wielu sesji kończy się rywalizacja o zatrzaskiwanie strony (zatrzaski są to obiekty używane do synchronizowania dostępu do stron bazy danych) na prawe strony listy połączonych poziomów list indeksów. To wąskie gardło uniemożliwia wykorzystanie pełnej przepustowości podsystemu pamięci masowej. Pamiętaj, że jeśli zdecydujesz się używać klawiszy sekwencyjnych i używasz ich numerycznych, zawsze możesz zacząć od najniższej wartości w typie, aby użyć całego zakresu. Na przykład zamiast zaczynać od 1 w typie INT, można rozpocząć od -2,147,483,648.

Należy rozważyć niesekwencyjne klucze, takie jak losowe wygenerowane za pomocą NEWID lub niestandardowe rozwiązanie. Próbując zmusić wiersz do już pełnej strony, SQL Server wykonuje klasyczną podział stron - przydziela nową stronę i przenosi połowę wierszy z oryginalnej strony do nowej. Podział strony ma koszt, a dodatkowo powoduje fragmentację indeksu. Fragmentacja indeksu może mieć negatywny wpływ na wydajność odczytów. Jednak pod względem wydajności insertów, jeśli podsystem pamięci zawiera wiele wrzecion i ładujesz dane z wielu sesji, kolejność losowa może być lepsza niż sekwencja pomimo podziałów.

Dzieje się tak dlatego, że nie ma gorącego miejsca na prawym końcu indeksu i korzystasz lepiej z dostępnej przepustowości podsystemu pamięci. Dobrym przykładem na benchmark pokazujący tę strategię można znaleźć na blogu Thomasa Kejsera pod adresem http://blog.kejser.org/2011/10/05/boosting-insert-speed-by-generating-scalable-keys/.

Źródło: Zapytania Microsoft® SQL Server® 2012 Exam 70-461 Training Kit