sql >> Databasteknik >  >> RDS >> Sqlserver

Skapa ett index på en tabellvariabel

Frågan är taggad SQL Server 2000, men till förmån för människor som utvecklar den senaste versionen ska jag ta upp det först.

SQL Server 2014

Förutom metoderna för att lägga till begränsningsbaserade index som diskuteras nedan tillåter SQL Server 2014 också att icke-unika index specificeras direkt med inline-syntax på tabellvariabler deklarationer.

Exempel på syntax för det är nedan.

/*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*/
);

Filtrerade index och index med inkluderade kolumner kan för närvarande inte deklareras med denna syntax dock SQL Server 2016 slappnar av detta lite ytterligare. Från CTP 3.1 är det nu möjligt att deklarera filtrerade index för tabellvariabler. Genom RTM kan vara fallet att inkluderade kolumner också är tillåtna men den nuvarande positionen är att de "sannolikt inte kommer att komma in i SQL16 på grund av resursbegränsningar"

/*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

Kan jag skapa ett index på Namn?

Kort svar:Ja.

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

Ett mer detaljerat svar finns nedan.

Traditionella tabeller i SQL Server kan antingen ha ett klustrat index eller är strukturerade som heaps.

Klustrade index kan antingen deklareras som unika för att inte tillåta dubbletter av nyckelvärden eller som standard till icke unika. Om inte unikt så lägger SQL Server tyst till en unikare till alla dubbletter av nycklar för att göra dem unika.

Icke-klustrade index kan också uttryckligen deklareras som unika. Annars för det icke-unika fallet lägger SQL Server till radlokaliseringen (klustrad indexnyckel eller RID för en heap) till alla indexnycklar (inte bara dubbletter) vilket säkerställer att de är unika igen.

I SQL Server 2000 - 2012 kan index på tabellvariabler endast skapas implicit genom att skapa en UNIQUE eller PRIMARY KEY begränsning. Skillnaden mellan dessa begränsningstyper är att primärnyckeln måste finnas på icke-nullbara kolumner. Kolumnerna som deltar i en unik begränsning kan vara nullbara. (även om SQL Servers implementering av unika begränsningar i närvaro av NULL s är inte enligt det som anges i SQL-standarden). En tabell kan också bara ha en primärnyckel men flera unika begränsningar.

Båda dessa logiska begränsningar är fysiskt implementerade med ett unikt index. Om inte annat uttryckligen anges är PRIMARY KEY kommer att bli det klustrade indexet och unika begränsningar som inte är klustrade men detta beteende kan åsidosättas genom att ange CLUSTERED eller NONCLUSTERED explicit med constraint-deklarationen (exempelsyntax)

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

Som ett resultat av ovanstående kan följande index implicit skapas på tabellvariabler i SQL Server 2000 - 2012.

+-------------------------------------+-------------------------------------+
|             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                                 |
+-------------------------------------+-------------------------------------+

Den sista kräver lite förklaring. I tabellvariabeldefinitionen i början av detta svar icke unik icke-klustrade index på Name simuleras av en unik index på Name,Id (kom ihåg att SQL Server tyst skulle lägga till den klustrade indexnyckeln till den icke unika NCI-nyckeln ändå).

Ett icke unikt klustrat index kan också uppnås genom att manuellt lägga till en IDENTITY kolumn för att fungera som en unikare.

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

Men detta är inte en korrekt simulering av hur ett icke unikt klustrat index normalt skulle implementeras i SQL Server eftersom detta lägger till "Uniqueifier" till alla rader. Inte bara de som kräver det.



  1. SQL NVARCHAR och VARCHAR gränser

  2. MySQL TAN() Funktion – Returnerar tangenten för ett värde i MySQL

  3. SQL WHERE-sats som matchar värden med efterföljande mellanslag

  4. Hur man övervakar MySQL-behållare med Prometheus - Implementering på fristående och Swarm::Del ett