Sdílet prostřednictvím


Rady k tabulce (Transact-SQL)

platí pro:SQL ServerAzure SQL Databaseazure SQL Managed InstanceSQL Database v Microsoft Fabric

Nápovědy k tabulce se používají k přepsání výchozího chování optimalizátoru dotazů během příkazu jazyka DML (Data Manipulat Language). Můžete zadat metodu uzamčení, jeden nebo více indexů, operaci zpracování dotazů, jako je prohledávání tabulky nebo hledání indexu nebo jiné možnosti. V klauzuli FROM příkazu DML jsou uvedeny rady tabulky a ovlivňují pouze tabulku nebo zobrazení odkazované v této klauzuli.

Opatrnost

Vzhledem k tomu, že optimalizátor dotazů SQL Serveru obvykle vybírá nejlepší plán provádění dotazu, doporučujeme, aby se rady používaly pouze jako poslední možnost zkušenými vývojáři a správci databází.

platí pro:

Transact-SQL konvence syntaxe

Syntax

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
}

Argumenty

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

S některými výjimkami jsou v klauzuli FROM podporovány rady tabulky pouze v případě, že jsou nápovědy zadány pomocí klíčového slova WITH. V závorkách je také nutné zadat nápovědu k tabulce.

Důležitý

Vynechání klíčového slova WITH je zastaralá funkce: Tato funkce se odebere v budoucí verzi SQL Serveru. Nepoužívejte tuto funkci v nové vývojové práci a naplánujte úpravu aplikací, které tuto funkci aktuálně používají.

Následující rady tabulky jsou povoleny s klíčovým slovem WITH a bez WITH: NOLOCK, READUNCOMMITTED, UPDLOCK, REPEATABLEREAD, SERIALIZABLE, READCOMMITTED, TABLOCK, TABLOCKX, PAGLOCK, ROWLOCK, NOWAIT, READPAST, XLOCK, SNAPSHOTa NOEXPAND. Pokud jsou tyto rady tabulky zadány bez klíčového slova WITH, měly by být pokyny zadány samostatně. Například:

FROM t (TABLOCK)

Při zadání nápovědy s jinou možností je nutné zadat nápovědu pomocí klíčového slova WITH:

FROM t WITH (TABLOCK, INDEX(myindex))

Doporučujeme použít čárky mezi radami tabulky.

Důležitý

Oddělení nápovědy mezerami místo čárkami je zastaralá funkce: Tato funkce se odebere v budoucí verzi SQL Serveru. Nepoužívejte tuto funkci v nové vývojové práci a naplánujte úpravu aplikací, které tuto funkci aktuálně používají.

NOEXPAND

Určuje, že se při zpracování dotazu optimalizátoru dotazů nezvětší žádná indexovaná zobrazení pro přístup k podkladovým tabulkám. Optimalizátor dotazů zachází s zobrazením jako s tabulkou s clusterovaným indexem. NOEXPAND platí jenom pro indexovaná zobrazení. Další informace naleznete v tématu Použití funkce NOEXPAND.

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

Syntaxe INDEX() určuje názvy nebo ID jednoho nebo více indexů, které se mají použít optimalizátorem dotazů při zpracování příkazu. Alternativní syntaxe INDEX = určuje jednu hodnotu indexu. Pro každou tabulku je možné zadat pouze jeden tip indexu.

Pokud existuje clusterovaný index, INDEX(0) vynutí kontrolu clusterovaného indexu a INDEX(1) vynutí kontrolu nebo hledání clusterovaného indexu. Pokud neexistuje žádný clusterovaný index, INDEX(0) vynutí prohledávání tabulky a INDEX(1) se interpretuje jako chyba.

Pokud se v jednom seznamu nápovědy používá více indexů, budou duplicity ignorovány a zbývající uvedené indexy se použijí k načtení řádků tabulky. Pořadí indexů v nápovědě indexu je významné. Funkce ANDing indexu také vynucuje více tipů indexu a optimalizátor dotazů na každý index, ke které se přistupuje, použije co nejvíce podmínek. Pokud kolekce indexů s nápovědou neobsahuje všechny sloupce odkazované dotazem, provede se načtení pro načtení zbývajících sloupců po načtení všech indexovaných sloupců databázový stroj SQL Serveru.

Poznámka

Pokud se v tabulce faktů ve spojení hvězdičkou použije nápověda indexu odkazující na více indexů, optimalizátor ignoruje nápovědu indexu a vrátí zprávu s upozorněním. U tabulky se zadaným nápovědou indexu také není povolený index ORing.

Maximální počet indexů v nápovědě tabulky je 250 neclusterovaných indexů.

KEEPIDENTITY

Platí pouze v příkazu INSERT, pokud je možnost BULK použita s OPENROWSET.

Určuje, že hodnota identity nebo hodnoty v importovaném datovém souboru se použijí pro sloupec identity. Pokud není zadaný KEEPIDENTITY, ověří se hodnoty identity pro tento sloupec, ale neimportují se a optimalizátor dotazů automaticky přiřadí jedinečné hodnoty na základě počátečních a přírůstkových hodnot zadaných během vytváření tabulky.

Důležitý

Pokud datový soubor neobsahuje hodnoty sloupce identity v tabulce nebo zobrazení a sloupec identity není posledním sloupcem v tabulce, musíte sloupec identity přeskočit. Další informace najdete v tématu Použití souboru formátu k přeskočení datového pole (SQL Server). Pokud se sloupec identity úspěšně přeskočí, optimalizátor dotazů automaticky přiřadí do importovaných řádků tabulky jedinečné hodnoty sloupce identity.

Příklad, který používá tento tip v příkazu INSERT ... SELECT * FROM OPENROWSET(BULK...), naleznete v tématu Zachovat hodnoty identity při hromadném importu dat (SQL Server).

Informace o kontrole hodnoty identity pro tabulku naleznete v tématu DBCC CHECKIDENT.

KEEPDEFAULTS

Platí pouze v příkazu INSERT, pokud je možnost BULK použita s OPENROWSET.

Určuje vložení výchozí hodnoty sloupce tabulky, pokud existuje, místo NULL, když záznam dat nemá hodnotu sloupce.

Příklad, který používá tento tip v příkazu INSERT ... SELECT * FROM OPENROWSET(BULK...), naleznete v tématu Zachovat hodnoty null nebo výchozí hodnoty při hromadném importu (SQL Server).

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

Určuje, že optimalizátor dotazů používá jako přístupovou cestu k datům v tabulce nebo zobrazení pouze operaci hledání indexu.

Poznámka

Od verze SQL Server 2008 R2 (10.50.x) Service Pack 1 je možné zadat také parametry indexu. V takovém případě optimalizátor dotazů bere v úvahu pouze operace hledání indexu prostřednictvím zadaného indexu pomocí alespoň zadaných sloupců indexu.

  • index_value

    Název indexu nebo hodnota ID indexu. ID indexu 0 (halda) nelze zadat. Pokud chcete vrátit název nebo ID indexu, zadejte dotaz na zobrazení katalogu sys.indexes.

  • index_column_name

    Název indexového sloupce, který se má zahrnout do operace hledání. Zadání FORCESEEK s parametry indexu je podobné použití FORCESEEK s nápovědou INDEX. Můžete však dosáhnout větší kontroly nad cestou přístupu používanou optimalizátorem dotazů zadáním indexu, který se má vyhledat, a sloupce indexu, které je potřeba zvážit v operaci hledání. Optimalizátor může v případě potřeby zvážit více sloupců. Pokud je například zadaný neclusterovaný index, optimalizátor se může rozhodnout, že kromě zadaných sloupců použije sloupce clusterovaného indexového klíče.

Nápovědu FORCESEEK lze zadat následujícími způsoby.

Syntax Příklad Popis
Bez nápovědy indexu nebo INDEX FROM dbo.MyTable WITH (FORCESEEK) Optimalizátor dotazů bere v úvahu pouze operace hledání indexů pro přístup k tabulce nebo zobrazení prostřednictvím libovolného relevantního indexu.
Kombinace s nápovědou INDEX FROM dbo.MyTable WITH (FORCESEEK, INDEX (MyIndex)) Optimalizátor dotazů považuje pouze operace hledání indexů pro přístup k tabulce nebo zobrazení prostřednictvím zadaného indexu.
Parametrizováno zadáním indexu a indexových sloupců FROM dbo.MyTable WITH (FORCESEEK (MyIndex (col1, col2, col3))) Optimalizátor dotazů bere v úvahu pouze operace hledání indexů pro přístup k tabulce nebo zobrazení prostřednictvím zadaného indexu pomocí alespoň zadaných sloupců indexu.

Při použití nápovědy FORCESEEK (s parametry indexu nebo bez nich) zvažte následující pokyny:

  • Nápovědu lze zadat jako nápovědu tabulky nebo jako nápovědu dotazu. Další informace o nápovědě k dotazům najdete v tématu Nápovědy k dotazům (Transact-SQL).
  • Chcete-li použít FORCESEEK v indexovaném zobrazení, musí být zadán také NOEXPAND nápovědy.
  • Nápovědu lze použít maximálně na tabulku nebo zobrazení.
  • Nápovědu nelze zadat pro vzdálený zdroj dat. Při zadání FORCESEEK s nápovědou indexu se vrátí chyba 7377 a při použití FORCESEEK bez nápovědy indexu se vrátí chyba 8180.
  • Pokud FORCESEEK způsobí, že se nenašly žádné plány, vrátí se chyba 8622.

Při zadání FORCESEEK s parametry indexu platí následující pokyny a omezení:

  • Nápovědu nelze zadat pro tabulku, která je cílem příkazu INSERT, UPDATEnebo DELETE.
  • Nápovědu nelze zadat v kombinaci s nápovědou INDEX nebo jinou nápovědou FORCESEEK.
  • Musí být zadán alespoň jeden sloupec a musí se jednat o počáteční klíčový sloupec.
  • Další sloupce indexu je možné zadat, ale klíčové sloupce se nedají přeskočit. Například pokud zadaný index obsahuje klíčové sloupce a, ba c, platná syntaxe by zahrnovala FORCESEEK (MyIndex (a)) a FORCESEEK (MyIndex (a, b). Neplatná syntaxe by zahrnovala FORCESEEK (MyIndex (c)) a FORCESEEK (MyIndex (a, c).
  • Pořadí názvů sloupců zadaných v nápovědě musí odpovídat pořadí sloupců v odkazovaném indexu.
  • Sloupce, které nejsou v definici klíče indexu, nelze zadat. Například v neclusterovaném indexu je možné zadat pouze definované sloupce klíče indexu. Sloupce clusterovaných klíčů, které jsou automaticky zahrnuty do indexu, nelze zadat, ale může je použít optimalizátor.
  • Index columnstore optimalizovaný pro paměť xVelocity nelze zadat jako parametr indexu. Vrátí se chyba 366.
  • Úprava definice indexu (například přidáním nebo odebráním sloupců) může vyžadovat úpravy dotazů, které na tento index odkazují.
  • Tento tip brání optimalizátoru v zvážení libovolného prostorového indexu nebo indexu XML v tabulce.
  • Nápovědu nelze zadat v kombinaci s nápovědou FORCESCAN.
  • U dělených indexů není možné v nápovědě k FORCESEEK zadat sloupec dělení implicitně přidaný SQL Serverem.

Opatrnost

Určení FORCESEEK s parametry omezuje počet plánů, které může optimalizátor zvážit více než při zadávání FORCESEEK bez parametrů. To může způsobit, že Plan cannot be generated dojde k chybě ve více případech.

FORCESCAN

platí pro: SQL Server 2008 R2 (10.50.x) Service Pack 1 a novější verze

Určuje, že optimalizátor dotazů používá jako přístupovou cestu k odkazované tabulce nebo zobrazení pouze operaci prohledávání indexu. Nápověda FORCESCAN může být užitečná pro dotazy, ve kterých optimalizátor podceňuje počet ovlivněných řádků a zvolí operaci hledání, a ne operaci prohledávání. Pokud k tomu dojde, množství paměti udělené pro operaci je příliš malé a je ovlivněn výkon dotazů.

FORCESCAN lze zadat pomocí nebo bez nápovědy INDEX. V kombinaci s nápovědou indexu (INDEX = index_name, FORCESCAN), optimalizátor dotazů při přístupu k odkazované tabulce bere v úvahu pouze cesty přístupu přes zadaný index. FORCESCAN lze zadat pomocí INDEX(0) nápovědy indexu k vynucení operace prohledávání tabulky na základní tabulce.

U dělených tabulek a indexů se FORCESCAN použije po odstranění oddílů prostřednictvím vyhodnocení predikátu dotazu. To znamená, že kontrola se použije jenom na zbývající oddíly, a ne na celou tabulku.

Nápověda pro FORCESCAN má následující omezení:

  • Nápovědu nelze zadat pro tabulku, která je cílem příkazu INSERT, UPDATEnebo DELETE.
  • Nápovědu nelze použít s více než jednou nápovědou indexu.
  • Tento tip brání optimalizátoru dotazů v zvážení libovolného prostorového indexu nebo indexu XML v tabulce.
  • Nápovědu nelze zadat pro vzdálený zdroj dat.
  • Nápovědu nelze zadat v kombinaci s nápovědou FORCESEEK.

HOLDLOCK

Ekvivalent SERIALIZABLE. Další informace naleznete v části SERIALIZABLE dále v tomto článku. HOLDLOCK se vztahuje pouze na tabulku nebo zobrazení, pro které je určena, a pouze po dobu trvání transakce definované příkazem, ve kterém se používá. HOLDLOCK nelze použít v příkazu SELECT, který obsahuje možnost FOR BROWSE.

IGNORE_CONSTRAINTS

Platí pouze v příkazu INSERT, pokud je možnost BULK použita s OPENROWSET.

Určuje, že operace hromadného importu ignoruje všechna omezení v tabulce. Ve výchozím nastavení INSERT kontroluje jedinečná omezení a omezení kontroly a omezení primárního a cizího klíče. Pokud je pro operaci hromadného importu zadán IGNORE_CONSTRAINTS, INSERT musí tato omezení v cílové tabulce ignorovat. Omezení UNIQUE, PRIMARY KEYnebo NOT NULL nemůžete zakázat.

Pokud vstupní data obsahují řádky, které porušují omezení, může být vhodné zakázat CHECK a FOREIGN KEY omezení. Zakázáním omezení CHECK a FOREIGN KEY můžete data importovat a pak pomocí příkazů Transact-SQL data vyčistit.

Pokud jsou však CHECK a FOREIGN KEY omezení ignorována, každé ignorované omezení tabulky se po operaci označí jako is_not_trusted v zobrazení katalogu sys.check_constraints nebo sys.foreign_keys. V určitém okamžiku byste měli zkontrolovat omezení celé tabulky. Pokud nebyla tabulka před hromadným importem prázdná, náklady na opětovné ověření omezení můžou překročit náklady na použití CHECK a FOREIGN KEY omezení přírůstkových dat.

IGNORE_TRIGGERS

Platí pouze v příkazu INSERT, pokud je možnost BULK použita s OPENROWSET.

Určuje, že všechny triggery definované v tabulce jsou ignorovány operací hromadného importu. Ve výchozím nastavení INSERT použije triggery.

Použijte IGNORE_TRIGGERS jenom v případě, že vaše aplikace nezávisí na žádných triggerech a maximalizaci výkonu je důležité.

NOLOCK

Ekvivalent READUNCOMMITTED. Další informace najdete v tématu READUNCOMMITTED dále v tomto článku.

Poznámka

Pro příkazy UPDATE nebo DELETE: Tato funkce se odebere v budoucí verzi SQL Serveru. Nepoužívejte tuto funkci v nové vývojové práci a naplánujte úpravu aplikací, které tuto funkci aktuálně používají.

NOWAIT

Dává databázovému stroji pokyn, aby vrátil zprávu, jakmile bude v tabulce zjištěn zámek. NOWAIT odpovídá zadání SET LOCK_TIMEOUT 0 pro konkrétní tabulku. Nápovědu NOWAIT nefunguje, pokud je zahrnuta také nápověda TABLOCK. Pokud chcete ukončit dotaz bez čekání, když použijete nápovědu TABLOCK, předkažte místo toho dotaz SET LOCK_TIMEOUT 0;.

PAGLOCK

Přebírá zámky stránek, ať už jsou jednotlivé zámky obvykle pořízené na řádcích nebo klíčích nebo kde se obvykle používá jeden zámek tabulky. Ve výchozím nastavení používá režim uzamčení vhodný pro operaci. Pokud jsou zadány v transakcích, které pracují na úrovni izolace SNAPSHOT, zámky stránek nejsou převzaty, pokud PAGLOCK není kombinován s dalšími radami tabulky, které vyžadují zámky, jako jsou UPDLOCK a HOLDLOCK.

READCOMMITTED

Určuje, že operace čtení splňují pravidla pro úroveň izolace READ COMMITTED pomocí uzamčení nebo správy verzí řádků. Pokud je možnost databáze READ_COMMITTED_SNAPSHOTOFF, databázový stroj získá sdílené zámky, protože data se čtou a po dokončení operace čtení tyto zámky uvolní. Pokud je možnost databáze READ_COMMITTED_SNAPSHOTON, databázový stroj nezíská zámky a používá správu verzí řádků. Další informace o úrovních izolace naleznete v tématu SET TRANSACTION ISOLATION LEVEL.

Poznámka

Pro příkazy UPDATE nebo DELETE: Tato funkce se odebere v budoucí verzi SQL Serveru. Nepoužívejte tuto funkci v nové vývojové práci a naplánujte úpravu aplikací, které tuto funkci aktuálně používají.

READCOMMITTEDLOCK

Určuje, že operace čtení splňují pravidla pro úroveň izolace READ COMMITTED pomocí uzamčení. Databázový stroj získá sdílené zámky při čtení dat a uvolní tyto zámky při dokončení operace čtení bez ohledu na nastavení READ_COMMITTED_SNAPSHOT databáze. Další informace o úrovních izolace naleznete v tématu SET TRANSACTION ISOLATION LEVEL. Tento tip nelze zadat v cílové tabulce příkazu INSERT; Vrátí se chyba 4140.

READPAST

Určuje, že databázový stroj nečte řádky, které jsou uzamčeny jinými transakcemi. Po zadání READPAST se zámky na úrovni řádků přeskočí, ale zámky na úrovni stránky se nepřekočí. To znamená, že databázový stroj přeskočí za řádky místo blokování aktuální transakce, dokud se zámky nevyvolají. Předpokládejme například, že tabulka T1 obsahuje jeden celočíselnou sloupec s hodnotami 1, 2, 3, 4, 5. Pokud transakce A změní hodnotu 3 na 8, ale ještě nebyla potvrzena, SELECT * FROM T1 (READPAST) zobrazí hodnoty 1, 2, 4, 5. READPAST se primárně používá k omezení kolizí uzamčení při implementaci pracovní fronty, která používá tabulku SQL Serveru. Čtenář fronty, který používá READPAST přeskočí předchozí položky fronty uzamčené jinými transakcemi na další dostupnou položku fronty, aniž by musel čekat, až ostatní transakce uvolní jejich zámky.

READPAST lze zadat pro libovolnou tabulku odkazovanou v příkazu UPDATE nebo DELETE a všechny tabulky odkazované v klauzuli FROM. Při zadání v příkazu UPDATE se READPAST použije pouze při čtení dat k identifikaci záznamů, které se mají aktualizovat, bez ohledu na to, kde je zadaný příkaz. READPAST nelze zadat pro tabulky v klauzuli INTO příkazu INSERT. Operace aktualizace nebo odstranění, které používají READPAST mohou blokovat čtení cizích klíčů nebo indexovaných zobrazení nebo při úpravách sekundárních indexů.

READPAST lze zadat pouze v transakcích, které fungují na úrovni izolace READ COMMITTED nebo REPEATABLE READ. Při zadání v transakcích, které pracují na úrovni izolace SNAPSHOT, musí být READPAST kombinovány s dalšími radami tabulky, které vyžadují zámky, jako jsou UPDLOCK a HOLDLOCK.

Pokud je možnost READ_COMMITTED_SNAPSHOT databáze nastavená na ON, není možné zadat nápovědu k tabulce READPAST a platí některé z následujících podmínek:

  • Úroveň izolace transakcí relace je READ COMMITTED.
  • V dotazu je také zadána nápověda k READCOMMITTED tabulce.

Chcete-li zadat READPAST nápovědu v těchto případech, odeberte READCOMMITTED nápovědu tabulky, pokud je k dispozici, a do dotazu zahrňte nápovědu READCOMMITTEDLOCK tabulky.

READUNCOMMITTED

Určuje, že jsou povolená zašpiněná čtení. Nejsou vydány žádné sdílené zámky, aby zabránily jiným transakcím v úpravě dat přečtených aktuální transakcí a výhradní zámky nastavené jinými transakcemi nezablokují aktuální transakci čtení uzamčených dat. Povolení nezašpiněných čtení může způsobit vyšší souběžnost, ale za cenu čtení úprav dat, které se pak vrátí zpět jinými transakcemi. To může generovat chyby pro vaši transakci, prezentovat uživatele s daty, která nebyla potvrzena, nebo způsobit, že se záznamy zobrazí dvakrát (nebo vůbec).

READUNCOMMITTED a nápovědy pro NOLOCK platí jenom pro zámky dat. Všechny dotazy, včetně dotazů s READUNCOMMITTED a NOLOCK nápovědou, získávají během kompilace a provádění zámky Sch-S (stabilita schématu). Z tohoto důvodu jsou dotazy blokovány, když souběžná transakce obsahuje zámek Sch-M (úpravy schématu) v tabulce. Například operace jazyka DDL (Data Definition Language) získá zámek Sch-M předtím, než upraví informace o schématu tabulky. Všechny souběžné dotazy, včetně dotazů spuštěných s READUNCOMMITTED nebo nápovědou NOLOCK, se při pokusu o získání zámku Sch-S zablokují. Naopak dotaz, který obsahuje zámek Sch-S blokuje souběžnou transakci, která se pokusí získat Sch-M zámek.

READUNCOMMITTED a NOLOCK nelze zadat pro tabulky upravené operacemi vložení, aktualizace nebo odstranění. Optimalizátor dotazů SQL Serveru ignoruje READUNCOMMITTED a NOLOCK nápovědy v klauzuli FROM, které platí pro cílovou tabulku příkazu UPDATE nebo DELETE.

Poznámka

Podpora použití READUNCOMMITTED a NOLOCK nápovědy v klauzuli FROM, která platí pro cílovou tabulku příkazu UPDATE nebo DELETE, se v budoucí verzi SQL Serveru odebere. Nepoužívejte tyto rady v tomto kontextu v nové vývojové práci a naplánujte úpravu aplikací, které je aktuálně používají.

Kolize uzamčení můžete minimalizovat při ochraně transakcí před nečtenými úpravami nepotvrzených dat pomocí některé z následujících možností:

  • Úroveň izolace READ COMMITTED s možností READ_COMMITTED_SNAPSHOT databáze nastavenou ON.
  • Úroveň izolace SNAPSHOT.

Další informace o úrovních izolace naleznete v tématu SET TRANSACTION ISOLATION LEVEL.

Poznámka

Pokud se při zadání READUNCOMMITTED zobrazí chybová zpráva 601, vyřešte ji tak, jak by se zobrazila chyba zablokování (chybová zpráva 1205) a zkuste příkaz zopakovat.

REPEATABLEREAD

Určuje, že kontrola se provádí se stejnou sémantikou uzamčení jako transakce spuštěná na úrovni izolace REPEATABLE READ. Další informace o úrovních izolace naleznete v tématu SET TRANSACTION ISOLATION LEVEL.

VESLOVÁ VIDLICE

Určuje, že zámky řádků se pořídí, když se obvykle zamknou zámky stránek nebo tabulek. Pokud jsou zadány v transakcích, které pracují na úrovni izolace SNAPSHOT, zámky řádků nejsou převzaty, pokud ROWLOCK není kombinován s dalšími pokyny tabulky, které vyžadují zámky, jako jsou UPDLOCK a HOLDLOCK. ROWLOCK nelze použít s tabulkou, která má clusterovaný index columnstore. Následující příklad vrátí chybu 651 do aplikace.

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

SERIALIZOVATELNÝ

Ekvivalent HOLDLOCK. Zneužívá sdílené zámky tím, že je drží, dokud se transakce nedokončí, namísto uvolnění sdíleného zámku, jakmile už není potřebná požadovaná tabulka nebo datová stránka, bez ohledu na to, zda byla transakce dokončena nebo ne. Kontrola se provádí se stejnou sémantikou jako transakce spuštěná na úrovni izolace SERIALIZABLE. Další informace o úrovních izolace naleznete v tématu SET TRANSACTION ISOLATION LEVEL.

SNÍMEK

platí pro: SQL Server 2014 (12.x) a novější verze

K tabulce optimalizované pro paměť se přistupuje v rámci izolace SNAPSHOT. SNAPSHOT lze použít pouze s tabulkami optimalizovanými pro paměť (ne s tabulkami založenými na disku), jak je vidět v následujícím příkladu. Další informace naleznete v tématu Úvod do Memory-Optimized tabulky.

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>

platí pro: SQL Server 2012 (11.x) a novější verze

Určuje maximální počet buněk, které se mají použít pro tessellating geometrie nebo geografického objektu. <integer_value> je hodnota mezi 1 a 8192.

Tato možnost umožňuje doladit dobu provádění dotazů úpravou kompromisu mezi dobou provádění primárního a sekundárního filtru. Větší číslo zkracuje dobu provádění sekundárního filtru, ale zvyšuje čas filtru primárního spuštění a menší počet snižuje dobu provádění primárního filtru, ale zvyšuje provádění sekundárního filtru. U hustších prostorových dat by mělo vyšší číslo generovat rychlejší dobu provádění tím, že poskytuje lepší aproximaci s primárním filtrem a snižuje dobu provádění sekundárního filtru. U více zhuštěných dat se nižším číslem sníží doba provádění primárního filtru.

Tato možnost funguje pro ruční i automatické tessellace mřížky.

TABLOCK

Určuje, že se získaný zámek použije na úrovni tabulky. Typ zámku, který se získá, závisí na prováděném příkazu. Například příkaz SELECT může získat sdílený zámek. Zadáním TABLOCKse sdílený zámek použije na celou tabulku místo na úrovni řádku nebo stránky. Pokud je zadán také HOLDLOCK, zámek tabulky se uchovává až do konce transakce.

Při importu dat do haldy pomocí příkazu INSERT INTO <target_table> SELECT <columns> FROM <source_table> můžete povolit minimální protokolování a optimální uzamčení příkazu zadáním TABLOCK nápovědy pro cílovou tabulku. Kromě toho musí být model obnovení databáze nastaven na jednoduchý nebo hromadně protokolovaný. Tip TABLOCK také umožňuje paralelní vkládání do indexů hald nebo clusterovaných indexů columnstore. Další informace naleznete v tématu INSERT.

Při použití s OPENROWSET poskytovatele hromadné sady řádků pro import dat do tabulky, TABLOCK umožňuje více klientům souběžně načítat data do cílové tabulky s optimalizovaným protokolováním a uzamčením. Další informace naleznete v tématu Požadavky pro minimální protokolování v hromadném importu.

TABLOCKX

Určuje, že se v tabulce převezme výhradní zámek.

UPDLOCK

Určuje, že se mají zamknout aktualizace a uchovávat, dokud transakce nebude dokončena. UPDLOCK používá zámky aktualizací pro operace čtení pouze na úrovni řádků nebo na úrovni stránky. Pokud se UPDLOCK zkombinuje s TABLOCKnebo je zámek na úrovni tabulky převzat z nějakého jiného důvodu, je místo toho pořízen exkluzivní zámek (X).

Při zadání UPDLOCK se READCOMMITTED a READCOMMITTEDLOCK rady na úrovni izolace ignorují. Pokud je například úroveň izolace relace nastavena na SERIALIZABLE a dotaz určuje (UPDLOCK, READCOMMITTED), READCOMMITTED tip je ignorován a transakce se spouští pomocí úrovně izolace SERIALIZABLE.

XLOCK

Určuje, že výhradní zámky se mají vzít a uchovávat, dokud transakce nebude dokončena. Pokud je zadána ROWLOCK, PAGLOCKnebo TABLOCK, platí výhradní zámky na odpovídající úroveň členitosti.

Poznámky

Nápovědy k tabulce se ignorují, pokud k tabulce není přístup plánem dotazu. Příčinou může být to, že optimalizátor nevyvolí přístup k tabulce vůbec nebo kvůli tomu, že se k indexované zobrazení přistupuje. V druhém případě může být přístup k indexovanému zobrazení znemožněný pomocí nápovědy k dotazu OPTION (EXPAND VIEWS).

Všechny nápovědy k uzamčení se rozšíří do všech tabulek a zobrazení, ke kterým přistupuje plán dotazu, včetně tabulek a zobrazení odkazovaných v zobrazení. SQL Server také provádí odpovídající kontroly konzistence zámků.

Nápovědy k uzamčení ROWLOCK, UPDLOCKa XLOCK, které získávají zámky na úrovni řádků, můžou umístit zámky na klíče indexu, nikoli na skutečné řádky dat. Pokud má například tabulka neclusterovaný index a příkaz SELECT, který používá nápovědu k uzamčení, zpracovává zakrývající index, zámek se získá na klíč indexu v indexovém indexu, nikoli na řádku dat v základní tabulce.

Pokud tabulka obsahuje počítané sloupce vypočítané výrazy nebo funkcemi, které přistupují ke sloupcům v jiných tabulkách, nebudou se v těchto tabulkách používat rady tabulek a nebudou se šířit. Například NOLOCK nápovědu k tabulce je určena pro tabulku v dotazu. Tato tabulka obsahuje počítané sloupce vypočítané kombinací výrazů a funkcí, které přistupují ke sloupcům v jiné tabulce. Tabulky odkazované výrazy a funkcemi při přístupu nepoužívají nápovědu k tabulce NOLOCK.

SQL Server neumožňuje pro každou z následujících skupin v klauzuli FROM nápovědu pro více tabulek:

  • Podrobné rady: PAGLOCK, NOLOCK, READCOMMITTEDLOCK, ROWLOCK, TABLOCKnebo TABLOCKX.
  • Rady na úrovni izolace: HOLDLOCK, NOLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE.

Filtrované nápovědy k indexu

Filtrovaný index lze použít jako nápovědu k tabulce, ale způsobí, že optimalizátor dotazů vygeneruje chybu 8622, pokud nepokrývá všechny řádky, které dotaz vybere. Následuje příklad neplatné filtrované nápovědy indexu. Příklad vytvoří filtrovaný index FIBillOfMaterialsWithComponentID a pak ho použije jako nápovědu indexu pro příkaz SELECT. Predikát filtrovaného indexu obsahuje řádky dat pro id komponent 533, 324 a 753. Predikát dotazu obsahuje také řádky dat pro identifikátory ComponentID 533, 324 a 753, ale rozšiřuje sadu výsledků tak, aby zahrnovala identifikátory ComponentID 855 a 924, které nejsou ve filtrovaného indexu. Optimalizátor dotazů proto nemůže použít filtrovaný nápovědu indexu a vygeneruje chybu 8622. Další informace najdete v tématu Vytvoření filtrovaných indexů.

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

Optimalizátor dotazů nebere v úvahu nápovědu indexu, pokud možnosti SET nemají požadované hodnoty pro filtrované indexy. Další informace naleznete v tématu CREATE INDEX.

Použití NOEXPAND

NOEXPAND platí pouze pro indexovaná zobrazení. Indexované zobrazení je zobrazení s jedinečným clusterovaným indexem vytvořeným na něm. Pokud dotaz obsahuje odkazy na sloupce, které jsou přítomné jak v indexovaných zobrazeních, tak v základních tabulkách, a optimalizátor dotazů určí, že použití indexovaného zobrazení poskytuje nejlepší metodu pro spuštění dotazu, optimalizátor dotazů použije index v zobrazení. Tato funkce se nazývá indexované zobrazení odpovídající. Před SQL Serverem 2016 (13.x) s aktualizací Service Pack 1 je automatické použití indexovaného zobrazení optimalizátorem dotazů podporováno pouze v konkrétních edicích SQL Serveru. V SQL Serveru 2016 (13.x) s aktualizací Service Pack 1 a novějšími verzemi podporují všechny edice automatické použití indexovaného zobrazení. Azure SQL Database a Azure SQL Managed Instance také podporují automatické použití indexovaných zobrazení bez zadání nápovědy NOEXPAND.

Další informace naleznete v tématu Průvodce architekturou zpracování dotazů.

Seznam funkcí podporovaných edicemi SQL Serveru ve Windows najdete tady:

Aby však optimalizátor dotazů zvážil indexovaná zobrazení pro porovnávání, nebo použít indexované zobrazení, na které odkazuje NOEXPAND nápověda, musí být následující možnosti SET nastaveny na ON.

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

1ARITHABORT je implicitně nastaven na ON, když je ANSI_WARNINGS nastavena na ON. Proto nemusíte toto nastavení upravovat ručně.

Také musí být možnost NUMERIC_ROUNDABORT nastavena na OFF.

Pokud chcete vynutit, aby optimalizátor dotazů používal index pro indexované zobrazení, zadejte možnost NOEXPAND. Tento tip lze použít pouze v případě, že je zobrazení také pojmenováno v dotazu. SQL Server neposkytuje nápovědu k vynucení použití konkrétního indexovaného zobrazení v dotazu, který nenázví zobrazení přímo v klauzuli FROM. Optimalizátor dotazů ale považuje použití indexovaných zobrazení, i když na něj přímo v dotazu neodkazuje. Databázový stroj SQL Serveru při použití nápovědy k tabulce NOEXPAND automaticky vytváří statistiky pouze v indexovaném zobrazení. Vynechání tohoto tipu může vést k upozornění plánu provádění na chybějící statistiky, které nelze vyřešit ručním vytvořením statistiky.

Při optimalizaci dotazů používá databázový stroj statistiku zobrazení, která byla vytvořena automaticky nebo ručně, když dotaz odkazuje přímo na zobrazení a použije se NOEXPAND nápověda.

Použití nápovědy k tabulce jako nápovědy k dotazu

nápovědy k tabulce lze také zadat jako nápovědu dotazu pomocí klauzule OPTION (TABLE HINT). Jako nápovědu k dotazu doporučujeme použít nápovědu tabulky pouze v kontextu průvodce plánem . U ad hoc dotazů zadejte tyto nápovědy pouze jako nápovědy k tabulce. Další informace najdete v tématu nápovědy k dotazům.

Dovolení

Nápovědy pro KEEPIDENTITY, IGNORE_CONSTRAINTSa IGNORE_TRIGGERS vyžadují ALTER oprávnění k tabulce.

Příklady

A. Určení metody uzamčení pomocí nápovědy TABLOCK

Následující příklad určuje, že sdílený zámek je převzat v tabulce Production.Product v databázi AdventureWorks2022 a je uložen až do konce příkazu UPDATE.

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

B. Určení operace hledání indexu pomocí nápovědy FORCESEEK

Následující příklad používá FORCESEEK nápovědu bez zadání indexu k vynucení optimalizátoru dotazu k provedení operace hledání indexu v tabulce Sales.SalesOrderDetail v databázi AdventureWorks2022.

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

Následující příklad používá FORCESEEK nápovědu s indexem k vynucení optimalizátoru dotazu k provedení operace hledání indexu u zadaného indexu a indexového sloupce.

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. Určení operace prohledávání indexu pomocí nápovědy FORCESCAN

Následující příklad používá FORCESCAN nápovědu k vynucení optimalizátoru dotazu k provedení operace prohledávání v tabulce Sales.SalesOrderDetail v databázi 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);