Können Sie in SQL Server 2000 einen Index für eine Tabellenvariable erstellen?
dh
DECLARE @TEMPTABLE TABLE (
[ID] [int] NOT NULL PRIMARY KEY
,[Name] [nvarchar] (255) COLLATE DATABASE_DEFAULT NULL
)
Kann ich einen Index für erstellen Name
?
sql
sql-server
tsql
indexing
table-variable
GordyII
quelle
quelle
CREATE TABLE #T1(X INT); CREATE TABLE #T2(X INT); CREATE INDEX IX ON #T1(X); CREATE INDEX IX ON #T2(X);
Antworten:
Die Frage ist mit SQL Server 2000 gekennzeichnet, aber zum Nutzen der Entwickler der neuesten Version werde ich dies zuerst ansprechen.
SQL Server 2014
Zusätzlich zu den unten beschriebenen Methoden zum Hinzufügen von auf Einschränkungen basierenden Indizes ermöglicht SQL Server 2014 auch die direkte Angabe nicht eindeutiger Indizes mit Inline-Syntax für Tabellenvariablendeklarationen.
Beispielsyntax dafür ist unten.
Gefilterte Indizes und Indizes mit eingeschlossenen Spalten können derzeit mit dieser Syntax nicht deklariert werden. SQL Server 2016 lockert dies jedoch etwas weiter. Ab CTP 3.1 können jetzt gefilterte Indizes für Tabellenvariablen deklariert werden. Nach RTM kann es vorkommen, dass eingeschlossene Spalten ebenfalls zulässig sind, aber die aktuelle Position ist, dass sie "aufgrund von Ressourcenbeschränkungen wahrscheinlich nicht in SQL16 gelangen".
SQL Server 2000 - 2012
Kurze Antwort: Ja.
Eine detailliertere Antwort finden Sie unten.
Herkömmliche Tabellen in SQL Server können entweder einen Clustered-Index haben oder als Heaps strukturiert sein .
Clustered-Indizes können entweder als eindeutig deklariert werden, um doppelte Schlüsselwerte nicht zuzulassen, oder standardmäßig als nicht eindeutig. Wenn dies nicht eindeutig ist, fügt SQL Server allen doppelten Schlüsseln stillschweigend einen eindeutigen Bezeichner 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 Key oder RID für einen Heap) allen Indexschlüsseln (nicht nur Duplikaten) hinzu, um sicherzustellen, dass sie eindeutig sind.
In SQL Server 2000 - 2012 können Indizes für Tabellenvariablen nur implizit durch Erstellen einer
UNIQUE
oder einerPRIMARY KEY
Einschränkung erstellt werden. Der Unterschied zwischen diesen Einschränkungstypen besteht darin, dass sich der Primärschlüssel in nicht nullbaren Spalten befinden muss. Die an einer eindeutigen Einschränkung beteiligten Spalten können nullwertfähig sein. (obwohl die Implementierung eindeutiger Einschränkungen durch SQL Server in Gegenwart vonNULL
s nicht den im SQL-Standard angegebenen entspricht). Eine Tabelle kann auch nur einen Primärschlüssel, aber mehrere eindeutige Einschränkungen haben.Diese beiden logischen Einschränkungen werden physisch mit einem eindeutigen Index implementiert. Wenn nicht explizit anders angegeben,
PRIMARY KEY
wird dies zum Clustered-Index und zu eindeutigen Constraints, die nicht geclustert sind. Dieses Verhalten kann jedoch durch AngabeCLUSTERED
oderNONCLUSTERED
explizit mit der Constraint-Deklaration (Beispielsyntax) überschrieben werden.Infolgedessen können die folgenden Indizes implizit für Tabellenvariablen in SQL Server 2000 - 2012 erstellt werden.
Der letzte bedarf einiger Erklärung. In der Tabellenvariablendefinition zu Beginn dieser Antwort wird der nicht eindeutige nicht gruppierte Index on
Name
durch einen eindeutigen Index on simuliertName,Id
(denken Sie daran, dass SQL Server den gruppierten Indexschlüssel ohnehin stillschweigend zum nicht eindeutigen NCI-Schlüssel hinzufügen würde).Ein nicht eindeutiger Clustered-Index kann auch durch manuelles Hinzufügen einer
IDENTITY
Spalte als eindeutiger Bezeichner erreicht werden.Dies ist jedoch keine genaue Simulation, wie ein nicht eindeutiger Clustered-Index normalerweise in SQL Server implementiert wird, da dadurch allen Zeilen der "Uniqueifier" hinzugefügt wird. Nicht nur diejenigen, die es benötigen.
quelle
Es versteht sich, dass es unter Leistungsgesichtspunkten keine Unterschiede zwischen @ temp-Tabellen und # temp-Tabellen gibt, die Variablen bevorzugen. Sie befinden sich am selben Ort (tempdb) und werden auf dieselbe Weise implementiert. Alle Unterschiede treten in zusätzlichen Funktionen auf. Sehen Sie sich diese erstaunlich vollständige Beschreibung an: /dba/16385/whats-the-difference-between-a-temp-table-and-table-variable-in-sql-server/16386#16386
Obwohl es Fälle gibt, in denen eine temporäre Tabelle nicht verwendet werden kann, z. B. in Tabellen- oder Skalarfunktionen, können Sie in den meisten anderen Fällen vor v2016 (in denen sogar gefilterte Indizes zu einer Tabellenvariablen hinzugefügt werden können) einfach eine # temp-Tabelle verwenden.
Der Nachteil bei der Verwendung benannter Indizes (oder Einschränkungen) in Tempdb besteht darin, dass die Namen dann zusammenstoßen können. Nicht nur theoretisch mit anderen Prozeduren, sondern oft recht einfach mit anderen Instanzen der Prozedur selbst, die versuchen würden, denselben Index auf ihre Kopie der # temp-Tabelle zu setzen.
Um Namenskonflikte zu vermeiden, funktioniert normalerweise so etwas:
Dies stellt sicher, dass der Name auch zwischen gleichzeitigen Ausführungen derselben Prozedur immer eindeutig ist.
quelle
Wenn die Tabellenvariable große Datenmengen enthält, können Sie anstelle der Tabellenvariablen (@table) keine temporäre Tabelle (#table) erstellen. Mit der Variablen .table kann nach dem Einfügen kein Index erstellt werden.
Erstellen Sie eine Tabelle mit einem eindeutigen Clustered-Index
Fügen Sie Daten in die Tabelle "#Table" von Temp ein
Erstellen Sie nicht gruppierte Indizes.
quelle