2016-09-14 2 views
1

Ich habe versucht, die Verwendung von Clustered-Indizes als Mittel zur Verbesserung der Abfrageleistung zu lesen.SQL Server Clustered-Index für nicht eindeutige Spalte

Im Wesentlichen habe ich eine "Nachrichten" -Tabelle, die in einer Chat-Anwendung verwendet wird. Wenn der Benutzer einen Chat öffnet, lesen wir den Nachrichtenverlauf aus der Tabelle basierend auf dem Kunden, mit dem der Benutzer spricht.

Die Nachrichten-Tabelle mit den Spalten gegliedert:

Id: CustomerId: Content

Die Abfrage am häufigsten auf dem Tisch verwendet wird so etwas wie

SELECT * FROM Message WHERE CustomerId = @CustomerId 

Meine Frage ist, , ist die CustomerId Spalte ein geeigneter Kandidat für einen Clustered-Index? Wenn das ID-Feld der Primärschlüssel ist, muss der SQL Server den Clustered-Index noch "einstufen"?

Die Tabelle wird schwer auf Auswahl und Einfügungen sein.

Antwort

1

Der Clustered-Index muss nicht eindeutig sein, daher ist es möglich.

Das Problem ist jedoch, dass SQL Server jedes Mal, wenn eine neue Nachricht eingefügt wird, einen Platz für die neue Zeile neben den anderen Zeilen für denselben Kunden finden muss. Dies kann oft ineffizient sein, da Seiten aufgeteilt werden müssen, was zu vielen halbvollen Seiten führt. Und die Dinge werden noch komplizierter, wenn Sie auch die Zeilen löschen.

Es gibt mehrere Optionen. In einer ausgelasteten Datenbank können Sie auf den Seiten Platz für zusätzliche Beilagen lassen. Oder eine andere Option besteht darin, die Tabelle basierend auf der Kunden-ID zu partitionieren. Es hängt alles ab.

Unter den meisten Umständen wäre eine Identitätsspalte in der Nachrichtentabelle der Primärschlüssel und der Clusterschlüssel. Ein zusätzlicher Index auf der Kundentabelle wäre ausreichend. Aber es gibt definitiv alternative Strukturen, die in einigen Szenarien besser funktionieren können.

0

Das Hinzufügen eines Clustered-Indexes für einen Schlüssel, auf dem bereits ein Primärschlüssel vorhanden ist, ist eine unnötige Duplizierung. Stattdessen sollte der Primärschlüssel-Constrain auch der Clustered-Index sein. Ihre Frage ist jedoch tatsächlich anders ...

ist die CustomerId-Spalte ein geeigneter Kandidat für einen Clustered-Index?

Man kann dies nicht ohne zu wissen, beantworten, wie Sie die Tabelle Abfrage wird. Es gibt zahlreiche Abfragemuster, für die diese Organisation nicht optimal sein wird (typische Beispiele sind Zeitreihen, in denen die Zeitspalte der geeignete gruppierte Schlüssel ist). Und es gibt ebenso viele Beispiele für Abfragen, für die der beste Clustered-Index ist. Unbeantwortbar.

Da das ID-Feld der Primärschlüssel ist, muss SQL Server den Clustered-Index noch "einstufen"?

Wenn der Index nicht erklärt einzigartig dann wird SQL Server die uniquifier Spalte hinzuzufügen. Die Spalte Wert wird sich jedoch niemals materialisieren, da keine Duplikate auftreten werden.

Ich habe eine ‚Nachrichten‘ Tabelle, die in einer Chat-Anwendung verwendet wird ... WHERE CustomerId = @Id ... das ID-Feld ist der Primärschlüssel

Pardon, aber das macht nichts Sinn. Was Sie sagen, ist, dass die Messages Tabelle nur eine Nachricht von jedem Kunden haben kann. Das würde eine schreckliche Chat-Erfahrung machen. Ich bin mir ziemlich sicher, dass deine Erklärung falsch ist.

Ich würde eine Customers Tabelle mit Clustered-Index und Primärschlüssel Einschränkung auf CustomerId erwarten. Die Messages Tabelle wird wahrscheinlich durch Chat-Raum oder eine andere Gruppe Organisation, der Paare, die Chat-Teilnehmer zu organisieren. Wenn die Chats immer zwischen einem und genau einem Kunden und einem Vertreter sind, dann kann der "Chatraum" der Kunde selbst sein. In jedem Fall würde die typische Abfrage einer solchen Messages Tabelle alle Nachrichten in einem Chat-Raum ausgetauscht werden, in der Reihenfolge oder alle Nachrichten ausgetauscht mit einem Kunden, in der Reihenfolge. Dies ist tatsächlich eine partitionierte Zeitreihe und wird am besten von einem gruppierten Index wie (chat_id, post_time) oder (customer_id, post_time) bedient. Beachten Sie, dass dieser nicht der Primärschlüssel ist, kann die Tabelle auch einen message_id als Primärschlüssel, aber nicht gruppiert.

+0

@GordonLinoff macht einen wichtigen Punkt, der ein Clustered-Schlüssel wie '(chat_id, post_time)' zu einer Fragmentierung führt als Daten an mehreren Punkten in dem Index eingefügt wird, aber in meiner Erfahrung, * wenn * es ein Problem wird, ist lösbar mit einfachem Reorganisieren oder Neuaufbau (eventuell mit einem niedrigen Füllfaktor). Wenn Sie stattdessen einen Clustered-Index auswählen, der nur die Semantik von Append-at-End-Semantik für die physische Organisation gewährleistet und Abfragen im Prozess benachteiligt, ist dies in der Regel weitaus schlechter. –

+0

'@Id' sollte die Kundennummer sein, wenn ein Argument in eine gespeicherte Prozedur übergeben wird. So würden Sie alle Nachrichten für einen Kunden nach ihrer ID suchen. Es war ein schlecht geschriebenes Beispiel. Ja, in diesem Fall ist die "Kunden-ID" im Grunde die Chatroom-Kennung. –