2011-01-05 7 views
3

Ich habe gerade einige Tests für Int PK gemacht, um Vs Guid PK zu verbinden.Int PK Inner Join Vs Guid PK Inner Beitreten auf SQL Server. Ausführungsplan

Tabellen Struktur und Anzahl der Datensätze wie die Suche:

alt text

Leistung von CRUD-Operationen EF4 verwenden, sind ziemlich ähnlich in beiden Fällen.

Es gibt wohlbekannte Aussage, dass Int PK bessere Leistung als Strings bei der Verwendung in Joins hat. So SQL Server Ausführungsplan mit inneren Joins sind völlig verschieden

Hier ist ein Ausführungsplan:

alt text

Als i Plan verstehen nach mit der Ausführung von oben Int verbinden eine bessere Leistung hat, weil es weniger Einnahme Ressourcen für Clustered Index Scan und es gibt zwei Möglichkeiten, bin ich richtig?

Kann jemand diesen Ausführungsplan in mehr Details erklären?

Ist dieses Beispiel genug, um zu zeigen, dass Int PK eine bessere Leistung in Joins hat?

+0

Hier ist meine Frage, was ist besser Int PK oder Guid PK http://StackOverflow.com/Questions/4593856/ef-4-0-guid-or-int-as-a-primary-key – Kuncevic

+0

I Frage mich, warum es keinen Merge-Join für den Guid verwendet hat. Vermutlich muss es 2 sortierte Eingaben von den Indizes gehabt haben? –

Antwort

2

Ich bin mir nicht ganz sicher, ob ich verstehe, was Sie versuchen, aus diesem Test zu erreichen oder erfahren, aber hier sind ein paar zufällige throughts, die mir in den Sinn kam, als ich Ihre Frage gelesen ...

1) In einem realen Anwendungsfall werden Sie wahrscheinlich nicht zwei ganze Tabellen miteinander verbinden, aber es wird Filter für andere Spalten usw. geben, die die Datensätze reduzieren, die in einer oder beiden Tabellen zusammengefügt werden sollen. Dies beeinflusst, welcher Join-Algorithmus am besten geeignet/am effektivsten ist.

Die obigen Pläne sind die Ergebnisse der Verbindung von zwei Tabellen zusammen, aber wenn Sie eine oder beide der Tabellen in einer anderen Spalte filtern sollten, dann könnte der Optimierer einen völlig anderen Join-Typ wählen.

2) Welcher Join-Typ am besten ist, wenn Sie GUID-Spalten verbinden, hängt stark davon ab, wie die GUIDs generiert werden. Wenn Sie eine große Anzahl von Guids verbinden, die völlig zufällig sind (z. B. generiert mit SQL Server's NewID() oder CLR Guid.NewGuid()), dann ist ein Hash-Join wahrscheinlich die beste Wahl. Wenn Sie jedoch eine kleinere Gruppe von sequenziellen (newsequentialid()/UuidCreateSequential()) oder sogar identische Guids verbinden, dann ist ein Loop-Join oft die effizienteste Wahl.

Der Optimierer verwendet Indexstatistiken, um zu ermitteln, welche Art von Join verwendet werden soll. Bei komplexen Abfragen mit vielen GUID-Joins kann es jedoch erforderlich sein, den Join-Typ mit Optimizer-Hinweisen zu erzwingen.


Kurz gesagt, wenn, was Sie versuchen, ob zu tun ist, entscheiden Sie GUID oder INT PKs dann eine reale Test ist eine bessere Wahl verwenden sollten. Erstellen Sie Tabellen, die zu Ihrem Anwendungsfall passen, füllen Sie sie mit einer großen Menge einigermaßen realistischer Beispieldaten aus, und führen Sie einige der Arten von Abfragen durch, die Sie sich auf der ganzen Linie vorstellen. Wenn Sie den gesamten Inhalt von zwei Dummy-Tabellen zusammenfügen, sagt das nicht wirklich etwas über die I/O-Auswirkungen aus Guid-Schlüsseln aus oder wie der Ausführungsplan für andere Abfragen aussehen wird, die int vs guid-Schlüssel enthalten.

Wenn Guid Schlüssel verwenden, sollten Sie die verschiedenen Optionen für sie zu erzeugen und daran denken, dass sequentielle guids mit oft ein guter Weg ist, liest übermäßige Seite zu vermeiden, wenn Sie viele Datensätze sind Verbindungs ​​...

+0

Ich versuche mir nur die Aussage zu beweisen, dass Int PK eine bessere Leistung in Joins hat als GUID PK – Kuncevic

+1

Ok. Die Antwort darauf lautet: "Es kommt darauf an". In einigen Situationen ist der Einfluss von Guid vs int vernachlässigbar. In anderen Situationen können zufällige Guids einen großen Einfluss auf die E/A haben. Wenn z.B. Sie haben eine sehr große Tabelle mit Millionen von Datensätzen und Sie werden nach 10000 Datensätzen suchen, die nacheinander generiert wurden (z. B. Befehle zwischen [somedate] und [someotherdate]). Zufällige Anleitungen können bedeuten, dass mindestens eine Seite pro Zeile nachgeschlagen wird , die sich in verschiedenen Teilen der Datendateien befinden, während int (oder sequenzielle Guids) bedeutet, dass Sie benachbarte Seiten erhalten (dh viel weniger Reads/I/O). – KristoferA

+0

... zu dem obigen hinzuzufügen, bedeutet das Verknüpfen von zwei ganzen Tabellen bedeutet, dass Sie alle Daten in beiden Tabellen trotzdem lesen, so dass der einzige I/O-Unterschied daran liegt, dass das GUID-Feld 16 Bytes anstelle von 4 verwendet Hier sehen Sie einen Unterschied, wenn die Datensätze, die Sie suchen, benachbart sind oder zufällig über den Index/die Tabelle verteilt sind. – KristoferA

3

Kimberly Tripp (die Queen of Indexing) hat einen ausgezeichneten Blog-Beitrag zum Thema:

Disk space is cheap.... that's not the point!

Sie schön zeigt, wie das Argument des „Speicherplatz ist billig - mit GUID statt INT tut nicht weh "ist in vielerlei Hinsicht völlig falsch.

2

Wenn Sie darüber nachdenken, wie intern, ein Computer-Werte vergleicht, wird deutlich.

  • Vergleichen von 2 ganzen Zahlen ist eine schnelle, Einzeloperation.
  • Vergleich 2 16-Byte-GUIDs nehmen mehrere Befehle (oder einer langen eins).
  • Darüber hinaus verwenden GUIDs 4-mal so viel Speicherplatz, was zu mehr Paging, schlechterer Cache-Nutzung und so weiter führen wird.

    Kimberly Tripps von Marc erwähnte Post beweist das.