Algorithme de sorting GUID SQL Server. Pourquoi?

Problème avec UniqueIdentifiers

Nous avons une database existante qui utilise beaucoup (malheureusement!) Des identifiants uniques à la fois comme keys primaires et comme colonnes nullables de certaines tables. Nous sums tombés sur une situation où certains rapports qui s'exécutent sur ces tables sortinge sur ces identifiants uniques car il n'y a pas d'autre colonne dans la table qui donnerait un sorting significatif (n'est-ce pas ironique!). L'intention était de sortinger de sorte qu'il montre les éléments dans l'ordre où ils ont été insérés mais ils n'ont pas été insérés en utilisant NewSequentialId () – d'où une perte de time.

Fait à propos de l'algorithm de sorting

SQL Server sortinge des identifiants uniques basés sur des groupes d'octets à partir du 5ème octet de fin (6 octets) et se déplace vers le 1er octet (4 octets) inversant l'ordre sur le 3ème octet (2 octets) de droite à gauche à gauche-droite,

Ma question

J'étais curieux de savoir s'il y avait une situation de la vie réelle que cette sorte de sorte aide du tout.

Comment SQL Server stocke-t-il l'identificateur unique en interne, ce qui pourrait fournir un aperçu de la raison pour laquelle il a cet algorithm de sorting whacky?

Référence:

Découverte par Alberto Ferrari du sorting GUID de SQL Server

Exemple

Les identifiants uniques sont sortingés comme indiqué ci-dessous lorsque vous utilisez un ordre de sorting sur une colonne identifiant unique ayant datatables ci-dessous.

Veuillez noter que datatables ci-dessous sont sortingées par ordre croissant et que la preference de sorting la plus élevée va du groupe 5ème octet vers le 1er groupe d'octets (vers l'arrière).

-- 1st byte group of 4 bytes sorted in the reverse (left-to-right) order below -- 01000000-0000-0000-0000-000000000000 10000000-0000-0000-0000-000000000000 00010000-0000-0000-0000-000000000000 00100000-0000-0000-0000-000000000000 00000100-0000-0000-0000-000000000000 00001000-0000-0000-0000-000000000000 00000001-0000-0000-0000-000000000000 00000010-0000-0000-0000-000000000000 -- 2nd byte group of 2 bytes sorted in the reverse (left-to-right) order below -- 00000000-0100-0000-0000-000000000000 00000000-1000-0000-0000-000000000000 00000000-0001-0000-0000-000000000000 00000000-0010-0000-0000-000000000000 -- 3rd byte group of 2 bytes sorted in the reverse (left-to-right) order below -- 00000000-0000-0100-0000-000000000000 00000000-0000-1000-0000-000000000000 00000000-0000-0001-0000-000000000000 00000000-0000-0010-0000-000000000000 -- 4th byte group of 2 bytes sorted in the straight (right-to-left) order below -- 00000000-0000-0000-0001-000000000000 00000000-0000-0000-0010-000000000000 00000000-0000-0000-0100-000000000000 00000000-0000-0000-1000-000000000000 -- 5th byte group of 6 bytes sorted in the straight (right-to-left) order below -- 00000000-0000-0000-0000-000000000001 00000000-0000-0000-0000-000000000010 00000000-0000-0000-0000-000000000100 00000000-0000-0000-0000-000000001000 00000000-0000-0000-0000-000000010000 00000000-0000-0000-0000-000000100000 00000000-0000-0000-0000-000001000000 00000000-0000-0000-0000-000010000000 00000000-0000-0000-0000-000100000000 00000000-0000-0000-0000-001000000000 00000000-0000-0000-0000-010000000000 00000000-0000-0000-0000-100000000000 

Code:

Le code d'Alberto s'étend pour indiquer que le sorting est sur les octets et non sur les bits individuels.

 With Test_UIDs As (-- 0 1 2 3 4 5 6 7 8 9 ABCDEF Select ID = 1, UID = cast ('00000000-0000-0000-0000-100000000000' as uniqueidentifier) Union Select ID = 2, UID = cast ('00000000-0000-0000-0000-010000000000' as uniqueidentifier) Union Select ID = 3, UID = cast ('00000000-0000-0000-0000-001000000000' as uniqueidentifier) Union Select ID = 4, UID = cast ('00000000-0000-0000-0000-000100000000' as uniqueidentifier) Union Select ID = 5, UID = cast ('00000000-0000-0000-0000-000010000000' as uniqueidentifier) Union Select ID = 6, UID = cast ('00000000-0000-0000-0000-000001000000' as uniqueidentifier) Union Select ID = 7, UID = cast ('00000000-0000-0000-0000-000000100000' as uniqueidentifier) Union Select ID = 8, UID = cast ('00000000-0000-0000-0000-000000010000' as uniqueidentifier) Union Select ID = 9, UID = cast ('00000000-0000-0000-0000-000000001000' as uniqueidentifier) Union Select ID = 10, UID = cast ('00000000-0000-0000-0000-000000000100' as uniqueidentifier) Union Select ID = 11, UID = cast ('00000000-0000-0000-0000-000000000010' as uniqueidentifier) Union Select ID = 12, UID = cast ('00000000-0000-0000-0000-000000000001' as uniqueidentifier) Union Select ID = 13, UID = cast ('00000000-0000-0000-0001-000000000000' as uniqueidentifier) Union Select ID = 14, UID = cast ('00000000-0000-0000-0010-000000000000' as uniqueidentifier) Union Select ID = 15, UID = cast ('00000000-0000-0000-0100-000000000000' as uniqueidentifier) Union Select ID = 16, UID = cast ('00000000-0000-0000-1000-000000000000' as uniqueidentifier) Union Select ID = 17, UID = cast ('00000000-0000-0001-0000-000000000000' as uniqueidentifier) Union Select ID = 18, UID = cast ('00000000-0000-0010-0000-000000000000' as uniqueidentifier) Union Select ID = 19, UID = cast ('00000000-0000-0100-0000-000000000000' as uniqueidentifier) Union Select ID = 20, UID = cast ('00000000-0000-1000-0000-000000000000' as uniqueidentifier) Union Select ID = 21, UID = cast ('00000000-0001-0000-0000-000000000000' as uniqueidentifier) Union Select ID = 22, UID = cast ('00000000-0010-0000-0000-000000000000' as uniqueidentifier) Union Select ID = 23, UID = cast ('00000000-0100-0000-0000-000000000000' as uniqueidentifier) Union Select ID = 24, UID = cast ('00000000-1000-0000-0000-000000000000' as uniqueidentifier) Union Select ID = 25, UID = cast ('00000001-0000-0000-0000-000000000000' as uniqueidentifier) Union Select ID = 26, UID = cast ('00000010-0000-0000-0000-000000000000' as uniqueidentifier) Union Select ID = 27, UID = cast ('00000100-0000-0000-0000-000000000000' as uniqueidentifier) Union Select ID = 28, UID = cast ('00001000-0000-0000-0000-000000000000' as uniqueidentifier) Union Select ID = 29, UID = cast ('00010000-0000-0000-0000-000000000000' as uniqueidentifier) Union Select ID = 30, UID = cast ('00100000-0000-0000-0000-000000000000' as uniqueidentifier) Union Select ID = 31, UID = cast ('01000000-0000-0000-0000-000000000000' as uniqueidentifier) Union Select ID = 32, UID = cast ('10000000-0000-0000-0000-000000000000' as uniqueidentifier) ) Select * From Test_UIDs Order By UID, ID 

    L'algorithm est documenté par les gars de SQL Server ici: Comment les GUID sont-ils comparés dans SQL Server 2005?

    De plus, le sorting suit les groupes d'octets endianness (voir ici: Identificateur global unique ). Les groupes 10-15 et 8-9 sont stockés en big endian (correspondant à la Data4 dans l'article wikipedia), ils sont donc comparés en big endian. Les autres groupes sont comparés en utilisant un petit boutiste.