Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Erstellen eines Index für eine Tabellenvariable

Die Frage ist mit SQL Server 2000 gekennzeichnet, aber für Leute, die mit der neuesten Version arbeiten, werde ich mich zuerst damit befassen.

SQL Server 2014

Zusätzlich zu den unten besprochenen Methoden zum Hinzufügen von auf Einschränkungen basierenden Indizes ermöglicht SQL Server 2014 auch die direkte Angabe von nicht eindeutigen Indizes mit Inline-Syntax für Tabellenvariablendeklarationen.

Beispielsyntax dafür ist unten.

/*SQL Server 2014+ compatible inline index syntax*/
DECLARE @T TABLE (
C1 INT INDEX IX1 CLUSTERED, /*Single column indexes can be declared next to the column*/
C2 INT INDEX IX2 NONCLUSTERED,
       INDEX IX3 NONCLUSTERED(C1,C2) /*Example composite index*/
);

Gefilterte Indizes und Indizes mit eingeschlossenen Spalten können derzeit jedoch nicht mit dieser Syntax deklariert werden SQL Server 2016 lockert das etwas weiter. Ab CTP 3.1 ist es nun möglich, gefilterte Indizes für Tabellenvariablen zu deklarieren. Durch RTM kann es sein Es kann vorkommen, dass eingeschlossene Spalten ebenfalls erlaubt sind, aber der aktuelle Stand ist, dass sie "aufgrund von Ressourcenbeschränkungen wahrscheinlich nicht in SQL16 landen werden"

/*SQL Server 2016 allows filtered indexes*/
DECLARE @T TABLE
(
c1 INT NULL INDEX ix UNIQUE WHERE c1 IS NOT NULL /*Unique ignoring nulls*/
)

SQL Server 2000–2012

Kann ich einen Index für Name erstellen?

Kurze Antwort:Ja.

DECLARE @TEMPTABLE TABLE (
  [ID]   [INT] NOT NULL PRIMARY KEY,
  [Name] [NVARCHAR] (255) COLLATE DATABASE_DEFAULT NULL,
  UNIQUE NONCLUSTERED ([Name], [ID]) 
  ) 

Eine ausführlichere Antwort finden Sie weiter unten.

Herkömmliche Tabellen in SQL Server können entweder einen gruppierten Index haben oder sind als Heaps strukturiert.

Clustered-Indizes können entweder als eindeutig deklariert werden, um doppelte Schlüsselwerte zu verhindern, oder standardmäßig auf nicht eindeutig festgelegt werden. Wenn nicht eindeutig, fügt SQL Server allen doppelten Schlüsseln stillschweigend einen Uniqueifier hinzu, um sie eindeutig zu machen.

Nicht gruppierte Indizes können auch explizit als eindeutig deklariert werden. Andernfalls fügt SQL Server für den nicht eindeutigen Fall den Zeilenlokator (Clustered-Index-Schlüssel oder RID für einen Heap) zu allen Indexschlüsseln (nicht nur Duplikaten) hinzu, wodurch wiederum sichergestellt wird, dass sie eindeutig sind.

In SQL Server 2000 - 2012 können Indizes auf Tabellenvariablen nur implizit durch Erstellen eines UNIQUE erstellt werden oder PRIMARY KEY Zwang. Der Unterschied zwischen diesen Einschränkungstypen besteht darin, dass sich der Primärschlüssel in einer oder mehreren Spalten befinden muss, die keine Nullwerte zulassen. Die an einer Unique-Einschränkung beteiligten Spalten können nullfähig sein. (obwohl die SQL Server-Implementierung von Unique Constraints in Anwesenheit von NULL s entspricht nicht den Angaben im SQL-Standard). Außerdem kann eine Tabelle nur einen Primärschlüssel, aber mehrere Unique Constraints haben.

Diese beiden logischen Einschränkungen werden physisch mit einem eindeutigen Index implementiert. Wenn nicht explizit anders angegeben der PRIMARY KEY wird zum geclusterten Index und eindeutige Einschränkungen werden nicht geclustert, aber dieses Verhalten kann durch Angabe von CLUSTERED außer Kraft gesetzt werden oder NONCLUSTERED explizit mit der Constraint-Deklaration (Beispielsyntax)

DECLARE @T TABLE
(
A INT NULL UNIQUE CLUSTERED,
B INT NOT NULL PRIMARY KEY NONCLUSTERED
)

Infolgedessen können die folgenden Indizes implizit für Tabellenvariablen in SQL Server 2000 - 2012 erstellt werden.

+-------------------------------------+-------------------------------------+
|             Index Type              | Can be created on a table variable? |
+-------------------------------------+-------------------------------------+
| Unique Clustered Index              | Yes                                 |
| Nonunique Clustered Index           |                                     |
| Unique NCI on a heap                | Yes                                 |
| Non Unique NCI on a heap            |                                     |
| Unique NCI on a clustered index     | Yes                                 |
| Non Unique NCI on a clustered index | Yes                                 |
+-------------------------------------+-------------------------------------+

Letzteres erfordert ein wenig Erklärung. In der Tabellenvariablendefinition am Anfang dieser Antwort das non unique nicht gruppierter Index auf Name wird durch ein einzigartiges simuliert Index auf Name,Id (Denken Sie daran, dass SQL Server den Clustered-Index-Schlüssel sowieso stillschweigend zum nicht eindeutigen NCI-Schlüssel hinzufügen würde).

Ein nicht eindeutiger Clustered-Index kann auch durch manuelles Hinzufügen einer IDENTITY erreicht werden Spalte, die als eindeutiges Merkmal fungiert.

DECLARE @T TABLE
(
A INT NULL,
B INT NULL,
C INT NULL,
Uniqueifier INT NOT NULL IDENTITY(1,1),
UNIQUE CLUSTERED (A,Uniqueifier)
)

Dies ist jedoch keine genaue Simulation dessen, wie ein nicht eindeutiger gruppierter Index normalerweise tatsächlich in SQL Server implementiert würde, da dies den "Uniqueifier" zu allen Zeilen hinzufügt. Nicht nur diejenigen, die es benötigen.