2009-06-01 3 views
2

Es besteht die Anforderung, GUID (s) als Primärschlüssel zu verwenden. Bin ich recht in der Annahme, dassguid Primärschlüsselerstellung für die schnellste Abfrage auswählen wo guid in (guid1, guid2, guid3 ...)

ProductID UNIQUEIDENTIFIER NOT NULL 
ROWGUIDCOL DEFAULT (NEWSEQUNTIALID()) PRIMARY KEY CLUSTERED 

die schnellste wählen für where-Klausel

productid in (guid1 , guid2 ,..., guidn)

geben und sich nicht verschlechtert nicht gruppierten

natural_key like 'Something*'

unabhängig wählen. Tabelle für die Abfrage nur von Benutzern und erstellt/neu erstellt von Grund auf neu.

Antwort

0

Ein Clustered-Index ist am besten geeignet, sucht zu reichen, so dass es Ihre Anfrage erfüllen könnten:

productid in (guid1 , guid2 ,..., guidn) 

hängt aber was sonst Sie auswählen, die Gruppierung durch, Bestellung von etc, wenn der Index eine Abdeckung sein Index. Andernfalls wird möglicherweise ein anderer nicht gruppierter Index vom Optimierer ausgewählt, gefolgt von einer Suche im Clustered-Index. Es hängt auch in gewissem Maße von der Anzahl der Zeilen in dieser Tabelle ab.

Auch ich glaube, Sie könnten NEWID verwenden möchten() in Bezug auf NEWSEQUENTIALID entgegensetzen()

+1

Eine disparate Liste von verschiedenen Werten in einer IN-Anweisung ist nicht genau eine Bereichsabfrage .... –

+0

@marc_s: Das ist ein guter Punkt! Aber sie sind sequentielle GUIDs, wie sie in der ursprünglichen Frage gestellt wurden, also denke ich, dass sie als Bereich auftreten könnten. –

+0

Ursprüngliche Sequenz ist zufällig wie von Lucene.Net Volltextindex zurückgegeben, aber wenn es eine Abfrage beschleunigt, kein Problem beim Sortieren von GUIDs im Speicher. – MicMit

3

Die Tatsache, Sie GUID als Clustered-Index verwenden werden definitiv negativ auf Ihre Leistung auswirken. Sogar mit dem NEWSEQUENTIALGUID sind die GUIDs nicht wirklich sequentiell - sie sind nur teilweise. Ihre Zufälligkeit von Natur aus wird definitiv zu einer höheren Indexfragmentierung und somit zu weniger optimalen Suchzeiten führen.

Wenn Sie eine 16-Byte-GUID als Clusterschlüssel haben, wird sie außerdem einem beliebigen nicht gruppierten Index für diese Tabelle hinzugefügt. Das hört sich vielleicht nicht so schlimm an, aber wenn du 10 Millionen hast. Zeilen, 10 nicht gruppierte Indizes, die eine 16-Byte-GUID vs. 4-Byte-INT verwenden kostet Sie 1,2 GByte Speicherplatz verschwendet - und nicht nur auf Festplatte (was billig ist), sondern auch in Ihrem SQL-Server-Speicher (seit SQL Server lädt immer ganze 8k Seiten in 8k Blöcke Speicher, egal wie voll oder leer sie sind.

Ich kann den Punkt der Verwendung einer GUID als Primärschlüssel sehen - sie sind fast 100% Garantie, einzigartig zu sein ist ansprechend für Entwickler. ABER: Als Clusterschlüssel sind sie ein Albtraum für Ihre Datenbank.

Meine beste Praxis: Wenn ich wirklich eine GUID als Primärschlüssel benötige, füge ich der Tabelle eine 4-Byte INT IDENTITY hinzu, die dann als Clusterschlüssel dient - die Ergebnisse sind viel besser!

Wenn Sie einen nicht gruppierten Primärschlüssel haben, sind Ihre Abfragen mit der Liste der GUIDs genauso schnell wie mit einem gruppierten Primärschlüssel. Wenn Sie keine GUIDs für Ihren Clusterschlüssel verwenden, wird Ihre Tabelle noch besser schlussendlich.

Lesen Sie mehr auf Clustertaste nach oben und warum es so wichtig, die richtigen in Kimberly Tripps' Blog zu holen - die die Königin von Indexing und kann die Dinge viel besser erklären als ich:

Marc

+0

Können wir sagen, dass im Allgemeinen, wenn GUID Primärschlüssel ist, es nicht geclustert sein sollte, hat das Clustering keinen Vorteil für die Auswahl in der Abfrage. Für den Fall, dass dies für meine Anwendung ausgelassen wurde, wird die Tabelle jedes Mal neu erstellt, die Benutzer fragen sie einfach ab, sobald sie fertig ist. – MicMit

1

Ebenso wie GUIDs schlecht sind (Antwort von marc_s), haben Sie auch eine IN-Klausel. Diese Schnäbel sind:

productid = guid1 OR productid = guid2 OR ... OR productid = guidn 

... in der Praxis, die auch nicht optimal ist.

Im Allgemeinen ist natural_key like 'Something%' wahrscheinlich am besten für einen gruppierten Index auf Ihrer natürlichen Schlüsselspalte.

+0

für Abfragen wie diese möchte ich die IN-CSV-Liste in eine Tabelle aufteilen und dann einfach mit ihr verbinden, so dass es einen Index verwenden wird. –

+0

Danke, ich benutze die gleiche Idee, wenn ich CSV verwenden muss – gbn