Delen via


Tabelhints (Transact-SQL)

van toepassing op:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL-database in Microsoft Fabric

Tabelhints worden gebruikt om het standaardgedrag van de queryoptimalisatie te overschrijven tijdens de DML-instructie (Data Manipulat Language). U kunt een vergrendelingsmethode, een of meer indexen, een bewerking voor het verwerken van query's opgeven, zoals een tabelscan of indexzoeken, of andere opties. Tabelhints worden opgegeven in de FROM component van de DML-instructie en zijn alleen van invloed op de tabel of weergave waarnaar in die component wordt verwezen.

Voorzichtigheid

Omdat de SQL Server-queryoptimalisatie doorgaans het beste uitvoeringsplan voor een query selecteert, raden we u aan om hints alleen te gebruiken als laatste redmiddel door ervaren ontwikkelaars en databasebeheerders.

van toepassing op:

Transact-SQL syntaxisconventies

Syntaxis

WITH  ( <table_hint> [ [ , ] ...n ] )

<table_hint> ::=
{ NOEXPAND
  | INDEX ( <index_value> [ , ...n ] ) | INDEX = ( <index_value> )
  | FORCESEEK [ ( <index_value> ( <index_column_name> [ , ... ] ) ) ]
  | FORCESCAN
  | HOLDLOCK
  | NOLOCK
  | NOWAIT
  | PAGLOCK
  | READCOMMITTED
  | READCOMMITTEDLOCK
  | READPAST
  | READUNCOMMITTED
  | REPEATABLEREAD
  | ROWLOCK
  | SERIALIZABLE
  | SNAPSHOT
  | SPATIAL_WINDOW_MAX_CELLS = <integer_value>
  | TABLOCK
  | TABLOCKX
  | UPDLOCK
  | XLOCK
}

<table_hint_limited> ::=
{
    KEEPIDENTITY
  | KEEPDEFAULTS
  | HOLDLOCK
  | IGNORE_CONSTRAINTS
  | IGNORE_TRIGGERS
  | NOLOCK
  | NOWAIT
  | PAGLOCK
  | READCOMMITTED
  | READCOMMITTEDLOCK
  | READPAST
  | REPEATABLEREAD
  | ROWLOCK
  | SERIALIZABLE
  | SNAPSHOT
  | TABLOCK
  | TABLOCKX
  | UPDLOCK
  | XLOCK
}

Argumenten

WITH ( <table_hint> ) [ , ] ...n ]

Met sommige uitzonderingen worden tabelhints alleen ondersteund in de FROM component wanneer de hints worden opgegeven met het WITH trefwoord. Tabelhints moeten ook worden opgegeven met haakjes.

Belangrijk

Het weglaten van het WITH trefwoord is een afgeschafte functie: deze functie wordt verwijderd in een toekomstige versie van SQL Server. Vermijd het gebruik van deze functie in nieuwe ontwikkelwerkzaamheden en plan om toepassingen te wijzigen die momenteel gebruikmaken van deze functie.

De volgende tabelhints zijn toegestaan met en zonder het trefwoord WITH: NOLOCK, READUNCOMMITTED, UPDLOCK, REPEATABLEREAD, SERIALIZABLE, READCOMMITTED, TABLOCK, TABLOCKX, PAGLOCK, ROWLOCK, NOWAIT, READPAST, XLOCK, SNAPSHOTen NOEXPAND. Wanneer deze tabelhints worden opgegeven zonder het WITH trefwoord, moeten de hints alleen worden opgegeven. Bijvoorbeeld:

FROM t (TABLOCK)

Wanneer de hint is opgegeven met een andere optie, moet de hint worden opgegeven met het WITH trefwoord:

FROM t WITH (TABLOCK, INDEX(myindex))

U wordt aangeraden komma's te gebruiken tussen tabelhints.

Belangrijk

Het scheiden van hints door spaties in plaats van komma's is een afgeschafte functie: deze functie wordt verwijderd in een toekomstige versie van SQL Server. Vermijd het gebruik van deze functie in nieuwe ontwikkelwerkzaamheden en plan om toepassingen te wijzigen die momenteel gebruikmaken van deze functie.

NOEXPAND

Hiermee geeft u op dat geïndexeerde weergaven niet worden uitgebreid voor toegang tot onderliggende tabellen wanneer de queryoptimalisatie wordt verwerkt door de queryoptimalisatie. De queryoptimalisatie behandelt de weergave als een tabel met geclusterde index. NOEXPAND is alleen van toepassing op geïndexeerde weergaven. Zie NOEXPAND-gebruiken voor meer informatie.

INDEX ( <index_value> [ , ...n ] ) | INDEX = ( <index_value> )

De syntaxis van de INDEX() geeft de namen of id's van een of meer indexen op die door de queryoptimalisatie moeten worden gebruikt wanneer deze de instructie verwerkt. Met de alternatieve INDEX = syntaxis wordt één indexwaarde opgegeven. Er kan slechts één indexhint per tabel worden opgegeven.

Als er een geclusterde index bestaat, INDEX(0) een geclusterde indexscan afdingt en INDEX(1) een geclusterde indexscan afding of zoek. Als er geen geclusterde index bestaat, INDEX(0) een tabelscan afdrijving en INDEX(1) wordt geïnterpreteerd als een fout.

Als er meerdere indexen worden gebruikt in één hintlijst, worden de duplicaten genegeerd en worden de rest van de vermelde indexen gebruikt om de rijen van de tabel op te halen. De volgorde van de indexen in de indexhint is aanzienlijk. Een hint voor meerdere indexen dwingt ook index-ANDing af en de queryoptimalisatie past zoveel mogelijk voorwaarden toe op elke index die wordt geopend. Als de verzameling hints geïndexeerde indexen niet alle kolommen bevat waarnaar wordt verwezen door de query, wordt er een ophaalbewerking uitgevoerd om de resterende kolommen op te halen nadat de SQL Server Database Engine alle geïndexeerde kolommen heeft opgehaald.

Notitie

Wanneer een indexhint die naar meerdere indexen verwijst, wordt gebruikt in de feitentabel in een sterdeelname, negeert de optimizer de indexhint en retourneert een waarschuwingsbericht. Index ORing is ook niet toegestaan voor een tabel met een indexhint die is opgegeven.

Het maximum aantal indexen in de tabelhint is 250 niet-geclusterde indexen.

KEEPIDENTITY

Alleen van toepassing in een INSERT instructie wanneer de optie BULK wordt gebruikt met OPENROWSET-.

Hiermee geeft u op dat de identiteitswaarde of -waarden in het geïmporteerde gegevensbestand moeten worden gebruikt voor de identiteitskolom. Als KEEPIDENTITY niet is opgegeven, worden de identiteitswaarden voor deze kolom geverifieerd, maar niet geïmporteerd en wijst de queryoptimalisatie automatisch unieke waarden toe op basis van de seed- en incrementele waarden die zijn opgegeven tijdens het maken van de tabel.

Belangrijk

Als het gegevensbestand geen waarden bevat voor de identiteitskolom in de tabel of weergave en de identiteitskolom niet de laatste kolom in de tabel is, moet u de identiteitskolom overslaan. Zie Een indelingsbestand gebruiken om een gegevensveld (SQL Server)over te slaan voor meer informatie. Als een identiteitskolom is overgeslagen, wijst de queryoptimalisatie automatisch unieke waarden voor de identiteitskolom toe aan de geïmporteerde tabelrijen.

Zie Identiteitswaarden behouden bij het bulksgewijs importeren van gegevens (SQL Server)voor een voorbeeld waarin deze hint wordt gebruikt in een INSERT ... SELECT * FROM OPENROWSET(BULK...) instructie.

Zie DBCC CHECKIDENTvoor informatie over het controleren van de identiteitswaarde voor een tabel.

KEEPDEFAULTS

Alleen van toepassing in een INSERT instructie wanneer de optie BULK wordt gebruikt met OPENROWSET-.

Hiermee geeft u invoeging van de standaardwaarde van een tabelkolom, indien aanwezig, in plaats van NULL wanneer de gegevensrecord geen waarde voor de kolom bevat.

Zie voor een voorbeeld dat deze hint in een INSERT ... SELECT * FROM OPENROWSET(BULK...)-instructie gebruikt, Null-waarden of standaardwaarden behouden tijdens het bulksgewijs importeren (SQL Server).

FORCESEEK [ ( <index_value> ( <index_column_name> [ , ...n ] ) ] ]

Hiermee geeft u op dat de queryoptimalisatie alleen een indexzoekbewerking gebruikt als het toegangspad naar de gegevens in de tabel of weergave.

Notitie

Vanaf SQL Server 2008 R2 (10.50.x) Service Pack 1 kunnen ook indexparameters worden opgegeven. In dat geval houdt de queryoptimalisatie alleen rekening met indexzoekbewerkingen via de opgegeven index met ten minste de opgegeven indexkolommen.

  • index_value

    De indexnaam of index-id-waarde. De index-id 0 (heap) kan niet worden opgegeven. Als u de indexnaam of -id wilt retourneren, voert u een query uit op de sys.indexes catalogusweergave.

  • index_column_name

    De naam van de indexkolom die moet worden opgenomen in de zoekbewerking. Het opgeven van FORCESEEK met indexparameters is vergelijkbaar met het gebruik van FORCESEEK met een INDEX hint. U kunt echter meer controle krijgen over het toegangspad dat door de queryoptimalisatie wordt gebruikt door zowel de index op te geven waarop moet worden gezocht als de indexkolommen die in de zoekbewerking moeten worden overwogen. De optimizer kan indien nodig rekening houden met meer kolommen. Als er bijvoorbeeld een niet-geclusterde index is opgegeven, kan de optimalisatie ervoor kiezen om naast de opgegeven kolommen geclusterde indexsleutelkolommen te gebruiken.

De FORCESEEK hint kan op de volgende manieren worden opgegeven.

Syntaxis Voorbeeld Beschrijving
Zonder index of INDEX hint FROM dbo.MyTable WITH (FORCESEEK) De queryoptimalisatie beschouwt alleen indexzoekbewerkingen om toegang te krijgen tot de tabel of weergave via een relevante index.
Gecombineerd met een INDEX hint FROM dbo.MyTable WITH (FORCESEEK, INDEX (MyIndex)) De queryoptimalisatie beschouwt alleen indexzoekbewerkingen om toegang te krijgen tot de tabel of weergave via de opgegeven index.
Geparameteriseerd door een index en indexkolommen op te geven FROM dbo.MyTable WITH (FORCESEEK (MyIndex (col1, col2, col3))) De queryoptimalisatie beschouwt alleen indexzoekbewerkingen om toegang te krijgen tot de tabel of weergave via de opgegeven index met ten minste de opgegeven indexkolommen.

Houd rekening met de volgende richtlijnen wanneer u de FORCESEEK hint (met of zonder indexparameters) gebruikt:

  • De hint kan worden opgegeven als een tabelhint of als een queryhint. Zie Queryhints (Transact-SQL)voor meer informatie over queryhints.
  • Als u FORCESEEK wilt toepassen op een geïndexeerde weergave, moet ook de NOEXPAND hint worden opgegeven.
  • De hint kan maximaal één keer per tabel of weergave worden toegepast.
  • De hint kan niet worden opgegeven voor een externe gegevensbron. Fout 7377 wordt geretourneerd wanneer FORCESEEK is opgegeven met een indexhint en fout 8180 wordt geretourneerd wanneer FORCESEEK wordt gebruikt zonder een indexhint.
  • Als FORCESEEK resulteert in geen plannen worden gevonden, wordt fout 8622 geretourneerd.

Wanneer FORCESEEK is opgegeven met indexparameters, zijn de volgende richtlijnen en beperkingen van toepassing:

  • De hint kan niet worden opgegeven voor een tabel die het doel is van een INSERT, UPDATEof DELETE instructie.
  • De hint kan niet worden opgegeven in combinatie met een INDEX hint of een andere FORCESEEK hint.
  • Ten minste één kolom moet worden opgegeven en moet de voorloopsleutelkolom zijn.
  • Aanvullende indexkolommen kunnen worden opgegeven, maar sleutelkolommen kunnen niet worden overgeslagen. Als de opgegeven index bijvoorbeeld de sleutelkolommen bevat a, ben c, bevat een geldige syntaxis FORCESEEK (MyIndex (a)) en FORCESEEK (MyIndex (a, b). Ongeldige syntaxis bevat FORCESEEK (MyIndex (c)) en FORCESEEK (MyIndex (a, c).
  • De volgorde van kolomnamen die in de hint zijn opgegeven, moet overeenkomen met de volgorde van de kolommen in de index waarnaar wordt verwezen.
  • Kolommen die niet in de definitie van de indexsleutel staan, kunnen niet worden opgegeven. In een niet-geclusterde index kunnen bijvoorbeeld alleen de gedefinieerde indexsleutelkolommen worden opgegeven. Gegroepeerde sleutelkolommen die automatisch in de index worden opgenomen, kunnen niet worden opgegeven, maar kunnen worden gebruikt door de optimalisatie.
  • Een columnstore-index die is geoptimaliseerd voor xVelocity-geheugen, kan niet worden opgegeven als een indexparameter. Fout 366 wordt geretourneerd.
  • Als u de indexdefinitie wijzigt (bijvoorbeeld door kolommen toe te voegen of te verwijderen), moet u mogelijk wijzigingen aanbrengen in de query's die naar die index verwijzen.
  • De hint voorkomt dat de optimizer rekening houdt met ruimtelijke of XML-indexen in de tabel.
  • De hint kan niet worden opgegeven in combinatie met de FORCESCAN hint.
  • Voor gepartitioneerde indexen kan de partitioneringskolom die door SQL Server wordt toegevoegd, niet worden opgegeven in de hint FORCESEEK.

Voorzichtigheid

Als u FORCESEEK met parameters opgeeft, wordt het aantal plannen beperkt dat door de optimizer meer kan worden overwogen dan wanneer u FORCESEEK zonder parameters opgeeft. Dit kan ertoe leiden dat er in meer gevallen een Plan cannot be generated fout optreedt.

FORCESCAN

Van toepassing op: SQL Server 2008 R2 (10.50.x) Service Pack 1 en nieuwere versies

Hiermee geeft u op dat de queryoptimalisatie alleen een indexscanbewerking gebruikt als het toegangspad naar de tabel of weergave waarnaar wordt verwezen. De FORCESCAN hint kan nuttig zijn voor query's waarin de optimizer het aantal betrokken rijen onderschat en een zoekbewerking kiest in plaats van een scanbewerking. Wanneer dit gebeurt, is de hoeveelheid geheugen die wordt verleend voor de bewerking te klein en worden de queryprestaties beïnvloed.

FORCESCAN kan worden opgegeven met of zonder INDEX hint. In combinatie met een indexhint (INDEX = index_name, FORCESCAN), houdt de queryoptimalisatie alleen rekening met scantoegangspaden via de opgegeven index bij toegang tot de opgegeven tabel. FORCESCAN kan worden opgegeven met de indexhint INDEX(0) om een tabelscanbewerking op de basistabel af te dwingen.

Voor gepartitioneerde tabellen en indexen wordt FORCESCAN toegepast nadat partities zijn geëlimineerd via evaluatie van querypredicaat. Dit betekent dat de scan alleen wordt toegepast op de resterende partities en niet op de hele tabel.

De FORCESCAN hint heeft de volgende beperkingen:

  • De hint kan niet worden opgegeven voor een tabel die het doel is van een INSERT, UPDATEof DELETE instructie.
  • De hint kan niet worden gebruikt met meer dan één indexhint.
  • De hint voorkomt dat de queryoptimalisatie rekening houdt met ruimtelijke of XML-indexen in de tabel.
  • De hint kan niet worden opgegeven voor een externe gegevensbron.
  • De hint kan niet worden opgegeven in combinatie met de FORCESEEK hint.

HOLDLOCK

Gelijk aan SERIALIZABLE. Zie SERIALIZABLE verderop in dit artikel voor meer informatie. HOLDLOCK is alleen van toepassing op de tabel of weergave waarvoor deze is opgegeven, en alleen voor de duur van de transactie die is gedefinieerd door de instructie waarin deze wordt gebruikt. HOLDLOCK kan niet worden gebruikt in een SELECT-instructie met de optie FOR BROWSE.

IGNORE_CONSTRAINTS

Alleen van toepassing in een INSERT instructie wanneer de optie BULK wordt gebruikt met OPENROWSET-.

Hiermee geeft u op dat de bulkimportbewerking eventuele beperkingen voor de tabel negeert. Standaard controleert INSERTunieke beperkingen en controleert u beperkingen en beperkingen voor primaire en refererende sleutels. Wanneer IGNORE_CONSTRAINTS is opgegeven voor een bulkimportbewerking, moet INSERT deze beperkingen voor een doeltabel negeren. U kunt UNIQUE, PRIMARY KEYof NOT NULL beperkingen niet uitschakelen.

Mogelijk wilt u CHECK en FOREIGN KEY beperkingen uitschakelen als de invoergegevens rijen bevatten die beperkingen schenden. Door de beperkingen voor CHECK en FOREIGN KEY uit te schakelen, kunt u de gegevens importeren en vervolgens Transact-SQL instructies gebruiken om de gegevens op te schonen.

Wanneer CHECK en FOREIGN KEY beperkingen echter worden genegeerd, wordt elke genegeerde beperking in de tabel gemarkeerd als is_not_trusted in de sys.check_constraints- of sys.foreign_keys catalogusweergave na de bewerking. Op een bepaald moment moet u de beperkingen voor de hele tabel controleren. Als de tabel niet leeg was vóór de bulkimportbewerking, kunnen de kosten voor het opnieuwvalideren van de beperking groter zijn dan de kosten voor het toepassen van CHECK en FOREIGN KEY beperkingen op de incrementele gegevens.

IGNORE_TRIGGERS

Alleen van toepassing in een INSERT instructie wanneer de optie BULK wordt gebruikt met OPENROWSET-.

Hiermee geeft u op dat triggers die in de tabel zijn gedefinieerd, worden genegeerd door de bulkimportbewerking. Standaard worden INSERT triggers toegepast.

Gebruik IGNORE_TRIGGERS alleen als uw toepassing niet afhankelijk is van triggers en de prestaties maximaliseren belangrijk is.

NOLOCK

Gelijk aan READUNCOMMITTED. Zie READUNCOMMITTED verderop in dit artikel voor meer informatie.

Notitie

Voor UPDATE- of DELETE-instructies: deze functie wordt verwijderd in een toekomstige versie van SQL Server. Vermijd het gebruik van deze functie in nieuwe ontwikkelwerkzaamheden en plan om toepassingen te wijzigen die momenteel gebruikmaken van deze functie.

NOWAIT

Hiermee geeft u de database-engine de opdracht om een bericht te retourneren zodra er een vergrendeling op de tabel is aangetroffen. NOWAIT is gelijk aan het opgeven van SET LOCK_TIMEOUT 0 voor een specifieke tabel. De NOWAIT hint werkt niet wanneer de TABLOCK hint ook is opgenomen. Als u een query wilt beëindigen zonder te wachten wanneer u de TABLOCK hint gebruikt, moet u de query vooraf laten gaan door SET LOCK_TIMEOUT 0;.

PAGLOCK

Hiermee worden paginavergrendelingen gebruikt waarbij afzonderlijke vergrendelingen gewoonlijk worden genomen op rijen of sleutels, of waarbij een enkele tabelvergrendeling gewoonlijk wordt gebruikt. Standaard wordt de vergrendelingsmodus gebruikt die geschikt is voor de bewerking. Wanneer deze zijn opgegeven in transacties die werken op het isolatieniveau van SNAPSHOT, worden paginavergrendelingen niet gebruikt, tenzij PAGLOCK wordt gecombineerd met andere tabelhints waarvoor vergrendelingen zijn vereist, zoals UPDLOCK en HOLDLOCK.

READCOMMITTED

Hiermee geeft u op dat leesbewerkingen voldoen aan de regels voor het READ COMMITTED isolatieniveau met behulp van vergrendeling of rijversiebeheer. Als de databaseoptie READ_COMMITTED_SNAPSHOT is OFF, verkrijgt de database-engine gedeelde vergrendelingen wanneer gegevens worden gelezen en worden deze vergrendelingen vrijgegeven wanneer de leesbewerking is voltooid. Als de databaseoptie READ_COMMITTED_SNAPSHOT is ON, verkrijgt de database-engine geen vergrendelingen en maakt gebruik van rijversiebeheer. Zie SET TRANSACTION ISOLATION LEVELvoor meer informatie over isolatieniveaus.

Notitie

Voor UPDATE- of DELETE-instructies: deze functie wordt verwijderd in een toekomstige versie van SQL Server. Vermijd het gebruik van deze functie in nieuwe ontwikkelwerkzaamheden en plan om toepassingen te wijzigen die momenteel gebruikmaken van deze functie.

READCOMMITTEDLOCK

Hiermee geeft u op dat leesbewerkingen voldoen aan de regels voor het READ COMMITTED isolatieniveau met behulp van vergrendeling. De database-engine verkrijgt gedeelde vergrendelingen wanneer gegevens worden gelezen en publiceert deze vergrendelingen wanneer de leesbewerking is voltooid, ongeacht de instelling van de READ_COMMITTED_SNAPSHOT-databaseoptie. Zie SET TRANSACTION ISOLATION LEVELvoor meer informatie over isolatieniveaus. Deze hint kan niet worden opgegeven in de doeltabel van een INSERT instructie; fout 4140 wordt geretourneerd.

READPAST

Hiermee geeft u op dat de database-engine geen rijen leest die zijn vergrendeld door andere transacties. Wanneer READPAST is opgegeven, worden vergrendelingen op rijniveau overgeslagen, maar worden vergrendelingen op paginaniveau niet overgeslagen. De database-engine slaat dus voorbij de rijen in plaats van de huidige transactie te blokkeren totdat de vergrendelingen worden vrijgegeven. Stel dat tabel T1 één geheel getal bevat met de waarden 1, 2, 3, 4, 5. Als transactie A de waarde van 3 naar 8 wijzigt maar nog niet is doorgevoerd, geeft SELECT * FROM T1 (READPAST) waarden 1, 2, 4, 5. READPAST wordt voornamelijk gebruikt om vergrendelingsconflicten te verminderen bij het implementeren van een werkwachtrij die gebruikmaakt van een SQL Server-tabel. Een wachtrijlezer die gebruikmaakt van READPAST voorbije wachtrijvermeldingen die door andere transacties zijn vergrendeld, overslaat naar de volgende beschikbare wachtrijvermelding, zonder dat u hoeft te wachten totdat de andere transacties hun vergrendelingen vrijgeven.

READPAST kan worden opgegeven voor elke tabel waarnaar wordt verwezen in een UPDATE- of DELETE-instructie, en elke tabel waarnaar wordt verwezen in een FROM-component. Wanneer deze is opgegeven in een UPDATE-instructie, wordt READPAST alleen toegepast bij het lezen van gegevens om te bepalen welke records moeten worden bijgewerkt, ongeacht waar in de instructie wordt opgegeven. READPAST kan niet worden opgegeven voor tabellen in de INTO component van een INSERT-instructie. Bewerkingen bijwerken of verwijderen die gebruikmaken van READPAST mogelijk blokkeren bij het lezen van refererende sleutels of geïndexeerde weergaven of bij het wijzigen van secundaire indexen.

READPAST kunnen alleen worden opgegeven in transacties die werken op de READ COMMITTED- of REPEATABLE READ isolatieniveaus. Wanneer deze zijn opgegeven in transacties die op het isolatieniveau van de SNAPSHOT worden uitgevoerd, moet READPAST worden gecombineerd met andere tabelhints waarvoor vergrendelingen zijn vereist, zoals UPDLOCK en HOLDLOCK.

De READPAST tabelhint kan niet worden opgegeven wanneer de READ_COMMITTED_SNAPSHOT databaseoptie is ingesteld op ON en aan een van de volgende voorwaarden wordt voldaan:

  • Het isolatieniveau van de transactie van de sessie wordt READ COMMITTED.
  • De READCOMMITTED tabelhint wordt ook opgegeven in de query.

Als u de READPAST hint in deze gevallen wilt opgeven, verwijdert u de READCOMMITTED tabelhint indien aanwezig en neemt u de READCOMMITTEDLOCK tabelhint op in de query.

READUNCOMMITTED

Hiermee geeft u op dat vuile leesbewerkingen zijn toegestaan. Er worden geen gedeelde vergrendelingen uitgegeven om te voorkomen dat andere transacties gegevens wijzigen die worden gelezen door de huidige transactie, en exclusieve vergrendelingen die door andere transacties zijn ingesteld, blokkeren niet dat de huidige transactie de vergrendelde gegevens leest. Het toestaan van vuile leesbewerkingen kan leiden tot hogere gelijktijdigheid, maar ten koste van het lezen van gegevenswijzigingen die vervolgens worden teruggedraaid door andere transacties. Dit kan fouten genereren voor uw transactie, gebruikers presenteren met gegevens die nooit zijn doorgevoerd of ertoe leiden dat gebruikers records tweemaal (of helemaal niet) zien.

READUNCOMMITTED en NOLOCK hints zijn alleen van toepassing op gegevensvergrendelingen. Alle query's, inclusief query's met READUNCOMMITTED en NOLOCK hints, verkrijgen Sch-S (schemastabiliteit) vergrendelingen tijdens de compilatie en uitvoering. Daarom worden query's geblokkeerd wanneer een gelijktijdige transactie een Sch-M -vergrendeling (schemawijziging) op de tabel bevat. Een DDL-bewerking (Data Definition Language) verkrijgt bijvoorbeeld een Sch-M-vergrendeling voordat de schemagegevens van de tabel worden gewijzigd. Eventuele gelijktijdige query's, waaronder query's die worden uitgevoerd met READUNCOMMITTED of NOLOCK hints, worden geblokkeerd bij het verkrijgen van een Sch-S-vergrendeling. Omgekeerd blokkeert een query met een Sch-S-vergrendeling een gelijktijdige transactie die probeert een Sch-M-vergrendeling te verkrijgen.

READUNCOMMITTED en NOLOCK kunnen niet worden opgegeven voor tabellen die zijn gewijzigd door invoeg-, update- of verwijderbewerkingen. De sql Server-queryoptimalisatie negeert de READUNCOMMITTED en NOLOCK hints in de FROM component die van toepassing zijn op de doeltabel van een UPDATE- of DELETE-instructie.

Notitie

Ondersteuning voor het gebruik van de READUNCOMMITTED- en NOLOCK hints in de FROM-component die van toepassing zijn op de doeltabel van een UPDATE- of DELETE-instructie, wordt verwijderd in een toekomstige versie van SQL Server. Vermijd het gebruik van deze hints in deze context in nieuwe ontwikkelwerkzaamheden en plan om toepassingen te wijzigen die deze momenteel gebruiken.

U kunt vergrendelingsconflicten minimaliseren terwijl u transacties beveiligt tegen vuile leesbewerkingen van niet-doorgevoerde gegevenswijzigingen met behulp van een van de volgende opties:

  • Het READ COMMITTED isolatieniveau met de READ_COMMITTED_SNAPSHOT databaseoptie ONingesteld.
  • Het SNAPSHOT isolatieniveau.

Zie SET TRANSACTION ISOLATION LEVELvoor meer informatie over isolatieniveaus.

Notitie

Als u foutbericht 601 krijgt wanneer READUNCOMMITTED is opgegeven, kunt u dit oplossen als een impassefout (foutbericht 1205) en voert u de instructie opnieuw uit.

HERHAALBAAR GELEZEN

Hiermee geeft u op dat een scan wordt uitgevoerd met dezelfde vergrendelingssemantiek als een transactie die wordt uitgevoerd op REPEATABLE READ isolatieniveau. Zie SET TRANSACTION ISOLATION LEVELvoor meer informatie over isolatieniveaus.

ROWLOCK

Hiermee geeft u op dat rijvergrendelingen worden genomen wanneer pagina- of tabelvergrendelingen gewoonlijk worden genomen. Wanneer deze zijn opgegeven in transacties die op het isolatieniveau SNAPSHOT, worden rijvergrendelingen niet gebruikt, tenzij ROWLOCK wordt gecombineerd met andere tabelhints waarvoor vergrendelingen zijn vereist, zoals UPDLOCK en HOLDLOCK. ROWLOCK kan niet worden gebruikt met een tabel met een geclusterde columnstore-index. In het volgende voorbeeld wordt fout 651 geretourneerd naar de toepassing.

UPDATE [dbo].[FactResellerSalesXL_CCI] WITH (ROWLOCK)
    SET UnitPrice = 50
WHERE ProductKey = 150;

SERIALIZABLE

Gelijk aan HOLDLOCK. Hiermee worden gedeelde vergrendelingen beperkter door ze vast te houden totdat een transactie is voltooid, in plaats van de gedeelde vergrendeling vrij te geven zodra de vereiste tabel of gegevenspagina niet meer nodig is, ongeacht of de transactie is voltooid of niet. De scan wordt uitgevoerd met dezelfde semantiek als een transactie die wordt uitgevoerd op het SERIALIZABLE isolatieniveau. Zie SET TRANSACTION ISOLATION LEVELvoor meer informatie over isolatieniveaus.

MOMENTOPNAME

Van toepassing op: SQL Server 2014 (12.x) en latere versies

De tabel die is geoptimaliseerd voor geheugen is toegankelijk onder SNAPSHOT isolatie. SNAPSHOT kan alleen worden gebruikt met tabellen die zijn geoptimaliseerd voor geheugen (niet met tabellen op basis van schijven), zoals te zien is in het volgende voorbeeld. Zie Inleiding tot Memory-Optimized tabellenvoor meer informatie.

SELECT *
FROM dbo.Customers AS c WITH (SNAPSHOT)
     LEFT OUTER JOIN dbo.[Order History] AS oh
         ON c.customer_id = oh.customer_id;

SPATIAL_WINDOW_MAX_CELLS = <integer_value>

Van toepassing op: SQL Server 2012 (11.x) en latere versies

Hiermee geeft u het maximum aantal cellen op dat moet worden gebruikt om een geometrie- of geografieobject tesselen. <integer_value> is een waarde tussen 1 en 8192.

Met deze optie kunt u de uitvoeringstijd van query's verfijnen door de balans tussen de uitvoeringstijd van het primaire en secundaire filter aan te passen. Een groter aantal vermindert de uitvoeringstijd van secundaire filters, maar verhoogt de primaire uitvoeringstijd van het uitvoeringsfilter en een kleiner aantal vermindert de uitvoeringstijd van het primaire filter, maar verhoogt de uitvoering van secundaire filters. Voor compactere ruimtelijke gegevens moet een hoger getal een snellere uitvoeringstijd produceren door een betere benadering te geven met het primaire filter en de secundaire uitvoeringstijd van het filter te verminderen. Voor meer parseringsgegevens vermindert een lager getal de uitvoeringstijd van het primaire filter.

Deze optie werkt zowel voor handmatige als automatische rasterbesturingselementen.

TABLOCK

Hiermee geeft u op dat de verkregen vergrendeling wordt toegepast op tabelniveau. Het type vergrendeling dat wordt verkregen, is afhankelijk van de instructie die wordt uitgevoerd. Een SELECT-instructie kan bijvoorbeeld een gedeelde vergrendeling verkrijgen. Door TABLOCKop te geven, wordt de gedeelde vergrendeling toegepast op de hele tabel in plaats van op rij- of paginaniveau. Als HOLDLOCK ook is opgegeven, wordt de tabelvergrendeling bewaard tot het einde van de transactie.

Wanneer u gegevens in een heap importeert met behulp van de instructie INSERT INTO <target_table> SELECT <columns> FROM <source_table>, kunt u minimale logboekregistratie en optimale vergrendeling voor de instructie inschakelen door de TABLOCK hint voor de doeltabel op te geven. Daarnaast moet het herstelmodel van de database worden ingesteld op eenvoudig of bulksgewijs vastgelegd. De TABLOCK hint maakt ook parallelle invoegingen mogelijk voor heaps of geclusterde columnstore-indexen. Zie INSERTvoor meer informatie.

Wanneer deze worden gebruikt met de OPENROWSET-provider bulksgewijs rijensetprovider om gegevens in een tabel te importeren, TABLOCK kunnen meerdere clients gelijktijdig gegevens in de doeltabel laden met geoptimaliseerde logboekregistratie en vergrendeling. Zie Vereisten voor minimale logboekregistratie in bulkimportvoor meer informatie.

TABLOCKX

Hiermee geeft u op dat een exclusieve vergrendeling op de tafel wordt genomen.

UPDLOCK

Hiermee geeft u op dat updatevergrendelingen moeten worden genomen en bewaard totdat de transactie is voltooid. UPDLOCK gebruikt updatevergrendelingen alleen voor leesbewerkingen op rij- of paginaniveau. Als UPDLOCK wordt gecombineerd met TABLOCKof als een vergrendeling op tabelniveau om een andere reden wordt genomen, wordt in plaats daarvan een exclusieve (X)-vergrendeling genomen.

Wanneer UPDLOCK is opgegeven, worden de hints READCOMMITTED en READCOMMITTEDLOCK isolatieniveau genegeerd. Als het isolatieniveau van de sessie bijvoorbeeld is ingesteld op SERIALIZABLE en een query (UPDLOCK, READCOMMITTED), wordt de READCOMMITTED hint genegeerd en wordt de transactie uitgevoerd met behulp van het SERIALIZABLE isolatieniveau.

XLOCK

Hiermee geeft u op dat exclusieve vergrendelingen moeten worden genomen en bewaard totdat de transactie is voltooid. Indien opgegeven met ROWLOCK, PAGLOCKof TABLOCK, zijn de exclusieve vergrendelingen van toepassing op het juiste granulariteitsniveau.

Opmerkingen

De tabelhints worden genegeerd als de tabel niet wordt geopend door het queryplan. Dit kan worden veroorzaakt doordat de optimizer ervoor kiest om helemaal geen toegang te krijgen tot de tabel, of omdat in plaats daarvan een geïndexeerde weergave wordt geopend. In het laatste geval kan het openen van een geïndexeerde weergave worden voorkomen met behulp van de OPTION (EXPAND VIEWS) queryhint.

Alle vergrendelingshints worden doorgegeven aan alle tabellen en weergaven die worden geopend door het queryplan, inclusief tabellen en weergaven waarnaar wordt verwezen in een weergave. Sql Server voert ook de bijbehorende consistentiecontroles voor vergrendelingen uit.

Vergrendelingshints ROWLOCK, UPDLOCKen XLOCK die vergrendelingen op rijniveau verkrijgen, kunnen vergrendelingen op indexsleutels plaatsen in plaats van de werkelijke gegevensrijen. Als een tabel bijvoorbeeld een niet-geclusterde index heeft en een SELECT instructie met behulp van een vergrendelingshint wordt verwerkt door een dekkingsindex, wordt een vergrendeling verkregen op de indexsleutel in de betreffende index in plaats van op de gegevensrij in de basistabel.

Als een tabel berekende kolommen bevat die worden berekend door expressies of functies die toegang hebben tot kolommen in andere tabellen, worden de tabelhints niet gebruikt voor deze tabellen en worden ze niet doorgegeven. Er wordt bijvoorbeeld een NOLOCK tabelhint opgegeven in een tabel in de query. Deze tabel heeft berekende kolommen die worden berekend door een combinatie van expressies en functies die toegang hebben tot kolommen in een andere tabel. De tabellen waarnaar wordt verwezen door de expressies en functies, gebruiken de NOLOCK tabelhint niet wanneer ze worden geopend.

SQL Server staat niet meer dan één tabelhint toe van elk van de volgende groepen voor elke tabel in de FROM-component:

  • Granulariteitshints: PAGLOCK, NOLOCK, READCOMMITTEDLOCK, ROWLOCK, TABLOCKof TABLOCKX.
  • Hints voor isolatieniveau: HOLDLOCK, NOLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE.

Gefilterde indexhints

Een gefilterde index kan worden gebruikt als een tabelhint, maar zorgt ervoor dat de queryoptimalisatie fout 8622 genereert als deze niet alle rijen omvat die door de query worden geselecteerd. Hier volgt een voorbeeld van een ongeldige gefilterde indexhint. In het voorbeeld wordt de gefilterde index gemaakt FIBillOfMaterialsWithComponentID en wordt deze vervolgens gebruikt als indexhint voor een SELECT-instructie. Het gefilterde indexpredicaat bevat gegevensrijen voor ComponentIDs 533, 324 en 753. Het querypredicaat bevat ook gegevensrijen voor ComponentIDs 533, 324 en 753, maar breidt de resultatenset uit met ComponentID's 855 en 924, die zich niet in de gefilterde index bevinden. Daarom kan de optimalisatiefunctie voor query's de gefilterde indexhint niet gebruiken en fout 8622 genereren. Zie Gefilterde indexen makenvoor meer informatie.

IF EXISTS (SELECT name FROM sys.indexes
           WHERE name = N'FIBillOfMaterialsWithComponentID'
                 AND object_id = OBJECT_ID(N'Production.BillOfMaterials'))
    DROP INDEX FIBillOfMaterialsWithComponentID
        ON Production.BillOfMaterials;
GO

CREATE NONCLUSTERED INDEX [FIBillOfMaterialsWithComponentID]
    ON Production.BillOfMaterials(ComponentID, StartDate, EndDate)
    WHERE ComponentID IN (533, 324, 753);
GO

SELECT StartDate, ComponentID
FROM Production.BillOfMaterials
WITH (INDEX (FIBillOfMaterialsWithComponentID))
WHERE ComponentID IN (533, 324, 753, 855, 924);
GO

De optimalisatiefunctie voor query's beschouwt geen indexhint als de SET-opties niet over de vereiste waarden beschikken voor gefilterde indexen. Zie CREATE INDEXvoor meer informatie.

NOEXPAND gebruiken

NOEXPAND geldt alleen voor geïndexeerde weergaven. Een geïndexeerde weergave is een weergave met een unieke geclusterde index die erop is gemaakt. Als een query verwijzingen bevat naar kolommen die zowel aanwezig zijn in een geïndexeerde weergave als basistabellen, en de queryoptimalisatie bepaalt dat het gebruik van de geïndexeerde weergave de beste methode biedt voor het uitvoeren van de query, gebruikt de queryoptimalisatie de index in de weergave. Deze functionaliteit wordt geïndexeerde weergave genoemd die overeenkomt met. Vóór SQL Server 2016 (13.x) met Service Pack 1 wordt automatisch gebruik van een geïndexeerde weergave door de queryoptimalisatie alleen ondersteund in specifieke edities van SQL Server. In SQL Server 2016 (13.x) met Service Pack 1 en latere versies ondersteunen alle edities het automatisch gebruik van een geïndexeerde weergave. Azure SQL Database en Azure SQL Managed Instance ondersteunen ook het automatisch gebruik van geïndexeerde weergaven zonder de NOEXPAND hint op te geven.

Zie architectuurhandleiding voor queryverwerkingvoor meer informatie.

Zie voor een lijst met functies die worden ondersteund door de edities van SQL Server in Windows:

Voor het optimaliseren van query's moet echter rekening worden gehouden met geïndexeerde weergaven voor overeenkomende weergaven of een geïndexeerde weergave gebruiken waarnaar wordt verwezen met de NOEXPAND hint, moeten de volgende SET opties worden ingesteld op ON.

  • ANSI_NULLS
  • ANSI_PADDING
  • ANSI_WARNINGS
  • ARITHABORT 1
  • CONCAT_NULL_YIELDS_NULL
  • QUOTED_IDENTIFIER

1ARITHABORT wordt impliciet ingesteld op ON wanneer ANSI_WARNINGS is ingesteld op ON. Daarom hoeft u deze instelling niet handmatig aan te passen.

De optie NUMERIC_ROUNDABORT moet ook worden ingesteld op OFF.

Als u wilt afdwingen dat de queryoptimalisatie een index gebruikt voor een geïndexeerde weergave, geeft u de optie NOEXPAND op. Deze hint kan alleen worden gebruikt als de weergave ook een naam heeft in de query. SQL Server biedt geen hint om te forceren dat een bepaalde geïndexeerde weergave wordt gebruikt in een query die de weergave niet rechtstreeks in de FROM-component een naam geeft. De queryoptimalisatie houdt echter rekening met het gebruik van geïndexeerde weergaven, zelfs als er niet rechtstreeks naar wordt verwezen in de query. De SQL Server Database Engine maakt alleen automatisch statistieken voor een geïndexeerde weergave wanneer een hint voor een NOEXPAND tabel wordt gebruikt. Als u deze hint weglaat, kan dit leiden tot waarschuwingen voor het uitvoeringsplan over ontbrekende statistieken die niet kunnen worden opgelost door handmatig statistieken te maken.

Tijdens het optimaliseren van query's gebruikt de database-engine weergavestatistieken die automatisch of handmatig zijn gemaakt wanneer de query rechtstreeks naar de weergave verwijst en de NOEXPAND hint wordt gebruikt.

Een tabelhint gebruiken als een queryhint

tabelhints kunnen ook worden opgegeven als een queryhint met behulp van de OPTION (TABLE HINT)-component. We raden u aan om een tabelhint alleen te gebruiken als een queryhint in de context van een planhandleiding. Geef voor ad-hocquery's deze hints alleen op als tabelhints. Zie queryhintsvoor meer informatie.

Machtigingen

Voor de KEEPIDENTITY, IGNORE_CONSTRAINTSen IGNORE_TRIGGERS hints zijn ALTER machtigingen voor de tabel vereist.

Voorbeelden

Een. De TABLOCK-hint gebruiken om een vergrendelingsmethode op te geven

In het volgende voorbeeld wordt aangegeven dat een gedeelde vergrendeling wordt uitgevoerd op de Production.Product tabel in de Database AdventureWorks2022 en wordt bewaard tot het einde van de instructie UPDATE.

UPDATE Production.Product WITH (TABLOCK)
    SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE 'BK-%';
GO

B. De HINT FORCESEEK gebruiken om een indexzoekbewerking op te geven

In het volgende voorbeeld wordt de FORCESEEK hint gebruikt zonder een index op te geven om de queryoptimalisatie te dwingen een indexzoekbewerking uit te voeren op de Sales.SalesOrderDetail tabel in de AdventureWorks2022-database.

SELECT *
FROM Sales.SalesOrderHeader AS h
     INNER JOIN Sales.SalesOrderDetail AS d WITH (FORCESEEK)
         ON h.SalesOrderID = d.SalesOrderID
WHERE h.TotalDue > 100
      AND (d.OrderQty > 5
           OR d.LineTotal < 1000.00);
GO

In het volgende voorbeeld wordt de FORCESEEK hint met een index gebruikt om de queryoptimalisatie te forceren om een indexzoekbewerking uit te voeren op de opgegeven index- en indexkolom.

SELECT h.SalesOrderID,
       h.TotalDue,
       d.OrderQty
FROM Sales.SalesOrderHeader AS h
     INNER JOIN Sales.SalesOrderDetail AS d
         WITH (FORCESEEK (PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID (SalesOrderID)))
         ON h.SalesOrderID = d.SalesOrderID
WHERE h.TotalDue > 100
      AND (d.OrderQty > 5
           OR d.LineTotal < 1000.00);
GO

C. Gebruik de hint FORCESCAN om een indexscanbewerking op te geven

In het volgende voorbeeld wordt de FORCESCAN hint gebruikt om de queryoptimalisatie te dwingen een scanbewerking uit te voeren op de Sales.SalesOrderDetail tabel in de Database AdventureWorks2022.

SELECT h.SalesOrderID,
       h.TotalDue,
       d.OrderQty
FROM Sales.SalesOrderHeader AS h
     INNER JOIN Sales.SalesOrderDetail AS d WITH (FORCESCAN)
         ON h.SalesOrderID = d.SalesOrderID
WHERE h.TotalDue > 100
      AND (d.OrderQty > 5
           OR d.LineTotal < 1000.00);