Udostępnij za pośrednictwem


Wskazówki dotyczące tabel (Transact-SQL)

Dotyczy:sql ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL Database w usłudze Microsoft Fabric

Wskazówki dotyczące tabel są używane do zastępowania domyślnego zachowania optymalizatora zapytań podczas instrukcji języka manipulowania danymi (DML). Można określić metodę blokowania, co najmniej jeden indeks, operację przetwarzania zapytań, taką jak skanowanie tabeli lub wyszukiwanie indeksu lub inne opcje. Wskazówki dotyczące tabeli są określone w klauzuli FROM instrukcji DML i mają wpływ tylko na tabelę lub widok, do którego odwołuje się ta klauzula.

Ostrożność

Ponieważ optymalizator zapytań programu SQL Server zazwyczaj wybiera najlepszy plan wykonania zapytania, zalecamy, aby wskazówki były używane tylko jako ostateczność dla doświadczonych deweloperów i administratorów baz danych.

Dotyczy:

Transact-SQL konwencje składni

Składnia

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 ]

W przypadku niektórych wyjątków wskazówki dotyczące tabeli są obsługiwane w klauzuli FROM tylko wtedy, gdy wskazówki są określone za pomocą słowa kluczowego WITH. Wskazówki dotyczące tabeli muszą być również określone nawiasami.

Ważny

Pominięcie słowa kluczowego WITH jest przestarzałą funkcją: ta funkcja zostanie usunięta w przyszłej wersji programu SQL Server. Unikaj używania tej funkcji w nowych pracach programistycznych i zaplanuj modyfikowanie aplikacji, które obecnie korzystają z tej funkcji.

Poniższe wskazówki dotyczące tabeli są dozwolone z słowem kluczowym WITH i bez tego słowa kluczowego: NOLOCK, READUNCOMMITTED, UPDLOCK, REPEATABLEREAD, SERIALIZABLE, READCOMMITTED, TABLOCK, TABLOCKX, PAGLOCK, ROWLOCK, NOWAIT, READPAST, XLOCK, SNAPSHOTi NOEXPAND. Gdy te wskazówki tabeli są określone bez słowa kluczowego WITH, wskazówki powinny być określone samodzielnie. Na przykład:

FROM t (TABLOCK)

Po określeniu wskazówki z inną opcją należy określić wskazówkę za pomocą słowa kluczowego WITH:

FROM t WITH (TABLOCK, INDEX(myindex))

Zalecamy używanie przecinków między wskazówkami tabeli.

Ważny

Oddzielanie wskazówek spacjami zamiast przecinków jest przestarzałą funkcją: ta funkcja zostanie usunięta w przyszłej wersji programu SQL Server. Unikaj używania tej funkcji w nowych pracach programistycznych i zaplanuj modyfikowanie aplikacji, które obecnie korzystają z tej funkcji.

NOEXPAND

Określa, że wszystkie indeksowane widoki nie są rozwinięte w celu uzyskania dostępu do bazowych tabel, gdy optymalizator zapytań przetwarza zapytanie. Optymalizator zapytań traktuje widok jak tabela z indeksem klastrowanym. NOEXPAND dotyczy tylko widoków indeksowanych. Aby uzyskać więcej informacji, zobacz Use NOEXPAND.

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

Składnia INDEX() określa nazwy lub identyfikatory co najmniej jednego indeksu, które mają być używane przez optymalizator zapytań podczas przetwarzania instrukcji. Alternatywna składnia INDEX = określa pojedynczą wartość indeksu. Można określić tylko jedną wskazówkę indeksu na tabelę.

Jeśli istnieje indeks klastrowany, INDEX(0) wymusza skanowanie indeksu klastrowanego, a INDEX(1) wymusza skanowanie lub wyszukiwanie klastrowanych indeksów. Jeśli żaden indeks klastrowany nie istnieje, INDEX(0) wymusza skanowanie tabeli, a INDEX(1) jest interpretowany jako błąd.

Jeśli wiele indeksów jest używanych na jednej liście wskazówek, duplikaty są ignorowane, a pozostałe wymienione indeksy są używane do pobierania wierszy tabeli. Kolejność indeksów w wskazówce indeksu jest znacząca. Wiele wskazówek indeksu wymusza również indeks ANDing, a optymalizator zapytań stosuje jak najwięcej warunków dla każdego indeksu, do których uzyskuje się dostęp. Jeśli kolekcja sugerowanych indeksów nie zawiera wszystkich kolumn, do których odwołuje się zapytanie, pobiera się pobieranie pozostałych kolumn po pobraniu pozostałych kolumn po pobraniu wszystkich indeksowanych kolumn przez aparat bazy danych programu SQL Server.

Nuta

Gdy wskazówka indeksu odwołująca się do wielu indeksów jest używana w tabeli faktów w sprzężeniu gwiazdy, optymalizator ignoruje wskazówkę indeksu i zwraca komunikat ostrzegawczy. Ponadto indeks ORing nie jest dozwolony dla tabeli z określoną wskazówką indeksu.

Maksymalna liczba indeksów w wskazówce tabeli to 250 indeksów nieklastrowanych.

KEEPIDENTITY

Dotyczy tylko instrukcji INSERT, gdy opcja BULK jest używana z OPENROWSET.

Określa, że wartość tożsamości lub wartości w zaimportowanych plikach danych mają być używane dla kolumny tożsamości. Jeśli nie określono KEEPIDENTITY, wartości tożsamości dla tej kolumny są weryfikowane, ale nie importowane, a optymalizator zapytań automatycznie przypisuje unikatowe wartości na podstawie wartości inicjacji i przyrostów określonych podczas tworzenia tabeli.

Ważny

Jeśli plik danych nie zawiera wartości kolumny tożsamości w tabeli lub widoku, a kolumna tożsamości nie jest ostatnią kolumną w tabeli, musisz pominąć kolumnę tożsamości. Aby uzyskać więcej informacji, zobacz Use a format file to skip a data field (SQL Server). Jeśli kolumna tożsamości zostanie pomyślnie pominięta, optymalizator zapytań automatycznie przypisze unikatowe wartości dla kolumny tożsamości do zaimportowanych wierszy tabeli.

Przykład, który używa tej wskazówki w instrukcji INSERT ... SELECT * FROM OPENROWSET(BULK...), zobacz Zachowaj wartości tożsamości podczas zbiorczego importowania danych (SQL Server).

Aby uzyskać informacje na temat sprawdzania wartości tożsamości dla tabeli, zobacz DBCC CHECKIDENT.

KEEPDEFAULTS

Dotyczy tylko instrukcji INSERT, gdy opcja BULK jest używana z OPENROWSET.

Określa wstawienie wartości domyślnej kolumny tabeli, jeśli istnieje, zamiast NULL, gdy rekord danych nie ma wartości dla kolumny.

Aby zapoznać się z przykładem użycia tej wskazówki w instrukcji INSERT ... SELECT * FROM OPENROWSET(BULK...), zobacz Zachowaj wartości null lub wartości domyślne podczas importowania zbiorczego (SQL Server).

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

Określa, że optymalizator zapytań używa tylko operacji wyszukiwania indeksu jako ścieżki dostępu do danych w tabeli lub widoku.

Nuta

Począwszy od programu SQL Server 2008 R2 (10.50.x) z dodatkiem Service Pack 1, można również określić parametry indeksu. W takim przypadku optymalizator zapytań uwzględnia tylko operacje wyszukiwania indeksów za pośrednictwem określonego indeksu przy użyciu co najmniej określonych kolumn indeksu.

  • index_value

    Nazwa indeksu lub wartość identyfikatora indeksu. Nie można określić identyfikatora indeksu 0 (sterta). Aby zwrócić nazwę indeksu lub identyfikator, wykonaj zapytanie dotyczące widoku wykazu sys.indexes.

  • index_column_name

    Nazwa kolumny indeksu do uwzględnienia w operacji wyszukiwania. Określanie FORCESEEK z parametrami indeksu jest podobne do używania FORCESEEK z wskazówką INDEX. Można jednak uzyskać większą kontrolę nad ścieżką dostępu używaną przez optymalizator zapytań, określając zarówno indeks do wyszukiwania, jak i kolumny indeksu do rozważenia w operacji wyszukiwania. Optymalizator może w razie potrzeby rozważyć więcej kolumn. Jeśli na przykład określono indeks nieklastrowany, optymalizator może użyć kolumn klucza indeksu klastrowanego oprócz określonych kolumn.

Wskazówkę FORCESEEK można określić w następujący sposób.

Składnia Przykład Opis
Bez indeksu lub wskazówki INDEX FROM dbo.MyTable WITH (FORCESEEK) Optymalizator zapytań uwzględnia tylko operacje wyszukiwania indeksu w celu uzyskania dostępu do tabeli lub wyświetlenia za pośrednictwem dowolnego odpowiedniego indeksu.
W połączeniu z wskazówką INDEX FROM dbo.MyTable WITH (FORCESEEK, INDEX (MyIndex)) Optymalizator zapytań uwzględnia tylko operacje wyszukiwania indeksu w celu uzyskania dostępu do tabeli lub widoku za pośrednictwem określonego indeksu.
Sparametryzowane przez określenie kolumn indeksu i indeksu FROM dbo.MyTable WITH (FORCESEEK (MyIndex (col1, col2, col3))) Optymalizator zapytań uwzględnia tylko operacje wyszukiwania indeksu w celu uzyskania dostępu do tabeli lub widoku za pośrednictwem określonego indeksu przy użyciu co najmniej określonych kolumn indeksu.

W przypadku korzystania z wskazówki FORCESEEK (z parametrami indeksu lub bez ich) należy wziąć pod uwagę następujące wskazówki:

  • Wskazówkę można określić jako wskazówkę tabeli lub jako wskazówkę zapytania. Aby uzyskać więcej informacji na temat wskazówek dotyczących zapytań, zobacz Wskazówki dotyczące zapytań (Transact-SQL).
  • Aby zastosować FORCESEEK do widoku indeksowanego, należy również określić wskazówkę NOEXPAND.
  • Wskazówkę można zastosować co najwyżej raz dla tabeli lub widoku.
  • Nie można określić wskazówki dla zdalnego źródła danych. Błąd 7377 jest zwracany po określeniu FORCESEEK z wskazówką indeksu i błąd 8180 jest zwracany, gdy FORCESEEK jest używany bez wskazówki indeksu.
  • Jeśli FORCESEEK nie znaleziono planów, zwracany jest błąd 8622.

Po określeniu FORCESEEK z parametrami indeksu obowiązują następujące wytyczne i ograniczenia:

  • Nie można określić wskazówki dla tabeli, która jest celem instrukcji INSERT, UPDATElub DELETE.
  • Nie można określić wskazówki w połączeniu z wskazówką INDEX lub inną wskazówką FORCESEEK.
  • Należy określić co najmniej jedną kolumnę i musi być kolumną klucza wiodącego.
  • Można określić dodatkowe kolumny indeksu, jednak nie można pominąć kolumn kluczowych. Jeśli na przykład określony indeks zawiera kolumny kluczy a, bi c, prawidłowa składnia będzie zawierać FORCESEEK (MyIndex (a)) i FORCESEEK (MyIndex (a, b). Nieprawidłowa składnia obejmuje FORCESEEK (MyIndex (c)) i FORCESEEK (MyIndex (a, c).
  • Kolejność nazw kolumn określonych w wskazówce musi być zgodna z kolejnością kolumn w indeksie, do których odwołuje się odwołanie.
  • Nie można określić kolumn, które nie mają definicji klucza indeksu. Na przykład w indeksie nieklastrowanym można określić tylko zdefiniowane kolumny klucza indeksu. Nie można określić kolumn kluczy klastrowanych, które są automatycznie uwzględnione w indeksie, ale mogą być używane przez optymalizator.
  • Nie można określić indeksu magazynu kolumn zoptymalizowanego pod kątem pamięci xVelocity jako parametru indeksu. Zwracany jest błąd 366.
  • Modyfikowanie definicji indeksu (na przykład przez dodawanie lub usuwanie kolumn) może wymagać modyfikacji zapytań odwołujących się do tego indeksu.
  • Wskazówka uniemożliwia optymalizatorowi rozważenie wszelkich indeksów przestrzennych lub XML w tabeli.
  • Nie można określić wskazówki w połączeniu z wskazówką FORCESCAN.
  • W przypadku indeksów partycjonowanych kolumna partycjonowania niejawnie dodana przez program SQL Server nie może być określona w wskazówce FORCESEEK.

Ostrożność

Określanie FORCESEEK z parametrami ogranicza liczbę planów, które mogą być brane pod uwagę przez optymalizatora więcej niż podczas określania FORCESEEK bez parametrów. Może to spowodować wystąpienie błędu Plan cannot be generated w kolejnych przypadkach.

FORCESCAN

Dotyczy: SQL Server 2008 R2 (10.50.x) z dodatkiem Service Pack 1 lub nowszym

Określa, że optymalizator zapytań używa tylko operacji skanowania indeksu jako ścieżki dostępu do tabeli lub widoku, do którego odwołuje się odwołanie. Wskazówka FORCESCAN może być przydatna w przypadku zapytań, w których optymalizator nie docenia liczby wierszy, których dotyczy problem, i wybiera operację wyszukiwania, a nie operację skanowania. W takim przypadku ilość pamięci przyznanej dla operacji jest zbyt mała i ma to wpływ na wydajność zapytań.

FORCESCAN można określić z lub bez wskazówki INDEX. W połączeniu z wskazówką indeksu (INDEX = index_name, FORCESCAN) optymalizator zapytań uwzględnia tylko ścieżki dostępu skanowania za pośrednictwem określonego indeksu podczas uzyskiwania dostępu do tabeli, do których odwołuje się odwołanie. FORCESCAN można określić za pomocą wskazówki indeksu INDEX(0) w celu wymuszenia operacji skanowania tabeli podstawowej.

W przypadku partycjonowanych tabel i indeksów FORCESCAN są stosowane po wyeliminowaniu partycji za pomocą oceny predykatu zapytania. Oznacza to, że skanowanie jest stosowane tylko do pozostałych partycji, a nie do całej tabeli.

Wskazówka FORCESCAN ma następujące ograniczenia:

  • Nie można określić wskazówki dla tabeli, która jest celem instrukcji INSERT, UPDATElub DELETE.
  • Wskazówka nie może być używana z więcej niż jedną wskazówką indeksu.
  • Wskazówka uniemożliwia optymalizatorowi zapytań rozważenie wszelkich indeksów przestrzennych lub XML w tabeli.
  • Nie można określić wskazówki dla zdalnego źródła danych.
  • Nie można określić wskazówki w połączeniu z wskazówką FORCESEEK.

BLOKADA BLOKADY

Odpowiednik SERIALIZABLE. Aby uzyskać więcej informacji, zobacz SERIALIZABLE w dalszej części tego artykułu. HOLDLOCK dotyczy tylko tabeli lub widoku, dla którego jest określony, i tylko przez czas trwania transakcji zdefiniowanej przez instrukcję, w której jest używana. HOLDLOCK nie można użyć w instrukcji SELECT, która zawiera opcję FOR BROWSE.

IGNORE_CONSTRAINTS

Dotyczy tylko instrukcji INSERT, gdy opcja BULK jest używana z OPENROWSET.

Określa, że operacja importowania zbiorczego ignoruje wszelkie ograniczenia w tabeli. Domyślnie INSERT sprawdza unikatowych ograniczeń i sprawdza ograniczenia i ograniczenia klucza podstawowego i obcego. Po określeniu IGNORE_CONSTRAINTS dla operacji importowania zbiorczego INSERT zignorować te ograniczenia w tabeli docelowej. Nie można wyłączyć ograniczeń UNIQUE, PRIMARY KEYlub NOT NULL.

Jeśli dane wejściowe zawierają wiersze naruszające ograniczenia, warto wyłączyć CHECK i FOREIGN KEY ograniczenia. Wyłączenie ograniczeń CHECK i FOREIGN KEY umożliwia zaimportowanie danych, a następnie użycie instrukcji Transact-SQL w celu wyczyszczenia danych.

Jednak gdy ograniczenia CHECK i FOREIGN KEY są ignorowane, każde zignorowane ograniczenie w tabeli jest oznaczone jako is_not_trusted w widoku sys.check_constraints lub sys.foreign_keys katalogu po operacji. W pewnym momencie należy sprawdzić ograniczenia dla całej tabeli. Jeśli tabela nie była pusta przed operacją importowania zbiorczego, koszt zmiany ograniczenia może przekroczyć koszt zastosowania CHECK i FOREIGN KEY ograniczeń do danych przyrostowych.

IGNORE_TRIGGERS

Dotyczy tylko instrukcji INSERT, gdy opcja BULK jest używana z OPENROWSET.

Określa, że wszystkie wyzwalacze zdefiniowane w tabeli są ignorowane przez operację importowania zbiorczego. Domyślnie INSERT stosuje wyzwalacze.

Użyj IGNORE_TRIGGERS tylko wtedy, gdy aplikacja nie zależy od żadnych wyzwalaczy, a maksymalizacja wydajności jest ważna.

NOLOCK

Odpowiednik READUNCOMMITTED. Aby uzyskać więcej informacji, zobacz READUNCOMMITTED w dalszej części tego artykułu.

Nuta

W przypadku instrukcji UPDATE lub DELETE: ta funkcja zostanie usunięta w przyszłej wersji programu SQL Server. Unikaj używania tej funkcji w nowych pracach programistycznych i zaplanuj modyfikowanie aplikacji, które obecnie korzystają z tej funkcji.

NOWAIT

Nakazuje aparatowi bazy danych zwrócenie komunikatu zaraz po napotkaniu blokady w tabeli. NOWAIT jest odpowiednikiem określania SET LOCK_TIMEOUT 0 dla określonej tabeli. Wskazówka NOWAIT nie działa, gdy dołączono również wskazówkę TABLOCK. Aby zakończyć zapytanie bez oczekiwania podczas korzystania z wskazówki TABLOCK, należy poprzeć zapytanie SET LOCK_TIMEOUT 0;.

STRONICOWANIE

Pobiera blokady stron, w których pojedyncze blokady są zwykle wykonywane w wierszach lub kluczach albo zwykle jest wykonywana pojedyncza blokada tabeli. Domyślnie używa trybu blokady odpowiedniego dla operacji. Po określeniu w transakcjach działających na poziomie izolacji SNAPSHOT blokady stron nie są wykonywane, chyba że PAGLOCK jest połączona z innymi wskazówkami tabeli, które wymagają blokad, takich jak UPDLOCK i HOLDLOCK.

READCOMMITTED

Określa, że operacje odczytu są zgodne z regułami dla poziomu izolacji READ COMMITTED przy użyciu blokady lub przechowywania wersji wierszy. Jeśli opcja bazy danych READ_COMMITTED_SNAPSHOT jest OFF, aparat bazy danych uzyskuje udostępnione blokady w miarę odczytywania danych i zwalnia te blokady po zakończeniu operacji odczytu. Jeśli opcja bazy danych READ_COMMITTED_SNAPSHOT jest ON, aparat bazy danych nie uzyskuje blokad i używa przechowywania wersji wierszy. Aby uzyskać więcej informacji na temat poziomów izolacji, zobacz SET TRANSACTION ISOLATION LEVEL.

Nuta

W przypadku instrukcji UPDATE lub DELETE: ta funkcja zostanie usunięta w przyszłej wersji programu SQL Server. Unikaj używania tej funkcji w nowych pracach programistycznych i zaplanuj modyfikowanie aplikacji, które obecnie korzystają z tej funkcji.

READCOMMITTEDLOCK

Określa, że operacje odczytu są zgodne z regułami dla poziomu izolacji READ COMMITTED przy użyciu blokady. Aparat bazy danych uzyskuje udostępnione blokady podczas odczytywania danych i zwalnia te blokady po zakończeniu operacji odczytu, niezależnie od ustawienia opcji READ_COMMITTED_SNAPSHOT bazy danych. Aby uzyskać więcej informacji na temat poziomów izolacji, zobacz SET TRANSACTION ISOLATION LEVEL. Nie można określić tej wskazówki w tabeli docelowej instrukcji INSERT; Zwracany jest błąd 4140.

READPAST

Określa, że aparat bazy danych nie odczytuje wierszy, które są zablokowane przez inne transakcje. Po określeniu READPAST blokady na poziomie wiersza są pomijane, ale blokady na poziomie strony nie są pomijane. Oznacza to, że aparat bazy danych pomija wcześniejsze wiersze zamiast blokować bieżącą transakcję do momentu zwolnienia blokad. Załóżmy na przykład, że tabela T1 zawiera jedną kolumnę całkowitą z wartościami 1, 2, 3, 4, 5. Jeśli transakcja A zmienia wartość od 3 do 8, ale nie została jeszcze zatwierdzona, SELECT * FROM T1 (READPAST) zwraca wartości 1, 2, 4, 5. READPAST służy głównie do zmniejszania rywalizacji o blokowanie podczas implementowania kolejki roboczej korzystającej z tabeli programu SQL Server. Czytnik kolejek, który używa READPAST pomija wcześniejsze wpisy kolejki zablokowane przez inne transakcje do następnego dostępnego wpisu kolejki, bez konieczności oczekiwania na zwolnienie blokad przez inne transakcje.

READPAST można określić dla dowolnej tabeli, do których odwołuje się instrukcja UPDATE lub DELETE, oraz dowolnej tabeli, do których odwołuje się klauzula FROM. Po określeniu w instrukcji UPDATEREADPAST jest stosowany tylko podczas odczytywania danych w celu zidentyfikowania rekordów do zaktualizowania, niezależnie od tego, gdzie w instrukcji jest określona. READPAST nie można określić dla tabel w klauzuli INTO instrukcji INSERT. Aktualizowanie lub usuwanie operacji korzystających z READPAST może blokować odczytywanie kluczy obcych lub indeksowanych widoków lub modyfikowanie indeksów pomocniczych.

READPAST można określić tylko w transakcjach działających na poziomie izolacji READ COMMITTED lub REPEATABLE READ. Po określeniu w transakcjach działających na poziomie izolacji SNAPSHOTREADPAST należy połączyć z innymi wskazówkami tabeli, które wymagają blokad, takich jak UPDLOCK i HOLDLOCK.

Nie można określić wskazówek tabeli READPAST, gdy opcja READ_COMMITTED_SNAPSHOT bazy danych jest ustawiona na ON, a jeden z następujących warunków jest spełniony:

  • Poziom izolacji transakcji sesji jest READ COMMITTED.
  • Wskazówka tabeli READCOMMITTED jest również określona w zapytaniu.

Aby określić wskazówkę READPAST w tych przypadkach, usuń wskazówkę tabeli READCOMMITTED, jeśli istnieje, i dołącz wskazówkę tabeli READCOMMITTEDLOCK w zapytaniu.

READUNCOMMITTED

Określa, że brudne odczyty są dozwolone. Nie są wystawiane blokady udostępnione, aby uniemożliwić innym transakcjom modyfikowanie danych odczytanych przez bieżącą transakcję, a blokady wyłączne ustawione przez inne transakcje nie blokują bieżącej transakcji odczytywania zablokowanych danych. Zezwolenie na zanieczyszczone odczyty może spowodować większą współbieżność, ale kosztem odczytywania modyfikacji danych, które następnie są wycofane przez inne transakcje. Może to generować błędy dla transakcji, przedstawiać użytkownikom dane, które nigdy nie zostały zatwierdzone, lub spowodować, że użytkownicy będą widzieć rekordy dwa razy (lub w ogóle nie).

READUNCOMMITTED i wskazówki NOLOCK dotyczą tylko blokad danych. Wszystkie zapytania, w tym zapytania z wskazówkami READUNCOMMITTED i NOLOCK, uzyskują blokady Sch-S (stabilność schematu) podczas kompilacji i wykonywania. W związku z tym zapytania są blokowane, gdy współbieżna transakcja przechowuje blokadę Sch-M (modyfikacja schematu) w tabeli. Na przykład operacja języka definicji danych (DDL) uzyskuje blokadę Sch-M przed zmodyfikowaniem informacji o schemacie tabeli. Wszystkie zapytania współbieżne, w tym zapytania uruchamiane przy użyciu READUNCOMMITTED lub wskazówek NOLOCK, są blokowane podczas próby uzyskania blokady Sch-S. Z drugiej strony zapytanie zawierające blokadę Sch-S blokuje współbieżną transakcję, która próbuje uzyskać blokadę Sch-M.

READUNCOMMITTED i NOLOCK nie można określić dla tabel zmodyfikowanych przez operacje wstawiania, aktualizowania lub usuwania. Optymalizator zapytań programu SQL Server ignoruje wskazówki dotyczące READUNCOMMITTED i NOLOCK w klauzuli FROM, która ma zastosowanie do tabeli docelowej instrukcji UPDATE lub DELETE.

Nuta

Obsługa użycia wskazówek dotyczących READUNCOMMITTED i NOLOCK w klauzuli FROM, która ma zastosowanie do tabeli docelowej instrukcji UPDATE lub DELETE zostanie usunięta w przyszłej wersji programu SQL Server. Unikaj używania tych wskazówek w tym kontekście w ramach nowych prac programistycznych i zaplanuj modyfikowanie aplikacji, które obecnie ich używają.

Rywalizację o blokowanie można zminimalizować, chroniąc transakcje przed brudnymi operacjami odczytu niezatwierdzonych modyfikacji danych przy użyciu jednej z następujących opcji:

  • Poziom izolacji READ COMMITTED z ustawioną opcją bazy danych READ_COMMITTED_SNAPSHOTON.
  • Poziom izolacji SNAPSHOT.

Aby uzyskać więcej informacji na temat poziomów izolacji, zobacz SET TRANSACTION ISOLATION LEVEL.

Nuta

Jeśli podczas READUNCOMMITTED określono komunikat o błędzie 601, rozwiąż go tak, jak w przypadku błędu zakleszczenia (komunikatu o błędzie 1205) i spróbuj ponownie wykonać instrukcję.

POWTARZALNY ODCZYT

Określa, że skanowanie jest wykonywane przy użyciu tej samej semantyki blokowania co transakcja uruchomiona na REPEATABLE READ poziomie izolacji. Aby uzyskać więcej informacji na temat poziomów izolacji, zobacz SET TRANSACTION ISOLATION LEVEL.

DULKA

Określa, że blokady wierszy są wykonywane, gdy zwykle są pobierane blokady strony lub tabeli. Po określeniu w transakcjach działających na poziomie izolacji SNAPSHOT blokady wierszy nie są wykonywane, chyba że ROWLOCK jest połączona z innymi wskazówkami tabeli, które wymagają blokad, takich jak UPDLOCK i HOLDLOCK. ROWLOCK nie można używać z tabelą z klastrowanym indeksem magazynu kolumn. Poniższy przykład zwraca błąd 651 do aplikacji.

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

SERIALIZACJI

Odpowiednik HOLDLOCK. Sprawia, że udostępnione blokady są bardziej restrykcyjne przez ich przechowywanie do momentu zakończenia transakcji, zamiast zwalniania udostępnionej blokady, gdy tylko wymagana tabela lub strona danych nie jest już potrzebna, niezależnie od tego, czy transakcja została ukończona, czy nie. Skanowanie jest wykonywane przy użyciu tej samej semantyki co transakcja uruchomiona na poziomie izolacji SERIALIZABLE. Aby uzyskać więcej informacji na temat poziomów izolacji, zobacz SET TRANSACTION ISOLATION LEVEL.

MIGAWKA

Dotyczy: SQL Server 2014 (12.x) i nowsze wersje

Tabela zoptymalizowana pod kątem pamięci jest dostępna w SNAPSHOT izolacji. SNAPSHOT można używać tylko z tabelami zoptymalizowanymi pod kątem pamięci (nie z tabelami opartymi na dyskach), jak pokazano w poniższym przykładzie. Aby uzyskać więcej informacji, zobacz wprowadzenie do tabel Memory-Optimized.

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>

Dotyczy: SQL Server 2012 (11.x) i nowsze wersje

Określa maksymalną liczbę komórek do użycia na potrzeby tessellating obiektu geometrii lub geografii. <integer_value> jest wartością z zakresu od 1 do 8192.

Ta opcja umożliwia precyzyjne dostrajanie czasu wykonywania zapytania przez dostosowanie kompromisu między podstawowym i pomocniczym czasem wykonywania filtru. Większa liczba zmniejsza pomocniczy czas wykonywania filtru, ale zwiększa czas filtru podstawowego wykonywania, a mniejsza liczba zmniejsza czas wykonywania filtru podstawowego, ale zwiększa wykonywanie pomocniczego filtru. W przypadku gęstszych danych przestrzennych większa liczba powinna generować krótszy czas wykonywania, dając lepsze przybliżenie podstawowego filtru i skrócenie pomocniczego czasu wykonywania filtru. W przypadku większej ilości rozrzedniejszych danych niższa liczba zmniejsza czas wykonywania filtru podstawowego.

Ta opcja działa zarówno w przypadku ręcznych, jak i automatycznych tessellacji siatki.

TABLOCK

Określa, że uzyskana blokada jest stosowana na poziomie tabeli. Typ nabytej blokady zależy od wykonywanej instrukcji. Na przykład instrukcja SELECT może uzyskać udostępnioną blokadę. Określając TABLOCK, blokada udostępniona jest stosowana do całej tabeli zamiast na poziomie wiersza lub strony. Jeśli HOLDLOCK jest również określona, blokada tabeli jest przechowywana do końca transakcji.

Podczas importowania danych do sterta przy użyciu instrukcji INSERT INTO <target_table> SELECT <columns> FROM <source_table> można włączyć minimalne rejestrowanie i optymalne blokowanie dla instrukcji, określając wskazówkę TABLOCK dla tabeli docelowej. Ponadto model odzyskiwania bazy danych musi być ustawiony na prosty lub rejestrowany zbiorczo. Wskazówka TABLOCK umożliwia również równoległe wstawianie do stertów lub klastrowanych indeksów magazynu kolumn. Aby uzyskać więcej informacji, zobacz INSERT.

W przypadku użycia z OPENROWSET dostawcy zestawów wierszy zbiorczych do importowania danych do tabeli, TABLOCK umożliwia wielu klientom równoczesne ładowanie danych do tabeli docelowej przy użyciu zoptymalizowanego rejestrowania i blokowania. Aby uzyskać więcej informacji, zobacz Wymagania wstępne dotyczące minimalnego rejestrowania w importowaniu zbiorczym.

TABLOCKX

Określa, że na stole jest pobierana blokada wyłączna.

UPDLOCK

Określa, że blokady aktualizacji mają być pobierane i przechowywane do momentu zakończenia transakcji. UPDLOCK przyjmuje blokady aktualizacji dla operacji odczytu tylko na poziomie wiersza lub na poziomie strony. Jeśli UPDLOCK jest w połączeniu z TABLOCKlub blokada na poziomie tabeli zostanie podjęta z jakiegoś innego powodu, zamiast tego zostanie podjęta blokada na wyłączność (X).

Po określeniu UPDLOCK wskazówki dotyczące poziomu izolacji READCOMMITTED i READCOMMITTEDLOCK są ignorowane. Jeśli na przykład poziom izolacji sesji jest ustawiony na SERIALIZABLE, a zapytanie określa (UPDLOCK, READCOMMITTED), wskazówka READCOMMITTED jest ignorowana, a transakcja jest uruchamiana przy użyciu poziomu izolacji SERIALIZABLE.

XLOCK

Określa, że blokady wyłącznych mają być pobierane i przechowywane do momentu zakończenia transakcji. W przypadku określenia z ROWLOCK, PAGLOCKlub TABLOCKblokady wyłączne mają zastosowanie do odpowiedniego poziomu szczegółowości.

Uwagi

Wskazówki dotyczące tabeli są ignorowane, jeśli tabela nie jest uzyskiwana przez plan zapytania. Może to być spowodowane tym, że optymalizator nie może w ogóle uzyskać dostępu do tabeli lub ponieważ zamiast tego uzyskuje się dostęp do indeksowanego widoku. W tym ostatnim przypadku dostęp do indeksowanego widoku można uniemożliwić przy użyciu wskazówki OPTION (EXPAND VIEWS) zapytania.

Wszystkie wskazówki dotyczące blokady są propagowane do wszystkich tabel i widoków, do których uzyskuje się dostęp w ramach planu zapytania, w tym tabel i widoków, do których odwołuje się widok. Ponadto program SQL Server wykonuje odpowiednie testy spójności blokady.

Wskazówki dotyczące blokad ROWLOCK, UPDLOCKi XLOCK, które uzyskują blokady na poziomie wiersza, mogą umieszczać blokady na kluczach indeksu, a nie na rzeczywistych wierszach danych. Jeśli na przykład tabela ma indeks nieklastrowany, a instrukcja SELECT korzystająca z wskazówki blokady jest obsługiwana przez indeks obejmujący, blokada jest uzyskiwana na kluczu indeksu indeksu w indeksie obejmującym, a nie w wierszu danych w tabeli bazowej.

Jeśli tabela zawiera obliczone kolumny obliczane przez wyrażenia lub funkcje, które uzyskują dostęp do kolumn w innych tabelach, wskazówki tabeli nie są używane w tych tabelach i nie są propagowane. Na przykład w tabeli w zapytaniu określono wskazówkę NOLOCK tabeli. Ta tabela zawiera kolumny obliczeniowe obliczane przez kombinację wyrażeń i funkcji, które uzyskują dostęp do kolumn w innej tabeli. Tabele, do których odwołuje się wyrażenia i funkcje, nie używają wskazówek tabeli NOLOCK podczas uzyskiwania dostępu.

Program SQL Server nie zezwala na więcej niż jedną wskazówkę tabeli z każdej z następujących grup dla każdej tabeli w klauzuli FROM:

  • Wskazówki dotyczące stopnia szczegółowości: PAGLOCK, NOLOCK, READCOMMITTEDLOCK, ROWLOCK, TABLOCKlub TABLOCKX.
  • Wskazówki dotyczące poziomu izolacji: HOLDLOCK, NOLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE.

Przefiltrowane wskazówki dotyczące indeksu

Filtrowany indeks może służyć jako wskazówka do tabeli, ale powoduje, że optymalizator zapytań generuje błąd 8622, jeśli nie obejmuje wszystkich wierszy wybranych przez zapytanie. Poniżej przedstawiono przykład nieprawidłowej przefiltrowanej wskazówki indeksu. Przykład tworzy filtrowany indeks FIBillOfMaterialsWithComponentID, a następnie używa go jako wskazówki indeksu dla instrukcji SELECT. Filtrowany predykat indeksu zawiera wiersze danych dla identyfikatorów składników 533, 324 i 753. Predykat zapytania zawiera również wiersze danych dla identyfikatorów składników 533, 324 i 753, ale rozszerza zestaw wyników tak, aby zawierał identyfikatory składników 855 i 924, które nie znajdują się w filtrowanym indeksie. W związku z tym optymalizator zapytań nie może użyć filtrowanej wskazówki indeksu i generuje błąd 8622. Aby uzyskać więcej informacji, zobacz Tworzenie filtrowanych indeksów.

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

Optymalizator zapytań nie uwzględnia wskazówki dotyczącej indeksu, jeśli opcje SET nie mają wymaganych wartości dla filtrowanych indeksów. Aby uzyskać więcej informacji, zobacz CREATE INDEX.

Używanie FUNKCJI NOEXPAND

NOEXPAND dotyczy tylko widoków indeksowanych . Widok indeksowany to widok z unikatowym indeksem klastrowanym utworzonym na nim. Jeśli zapytanie zawiera odwołania do kolumn, które znajdują się zarówno w indeksowanym widoku, jak i w tabelach podstawowych, a optymalizator zapytań określa, że użycie indeksowanego widoku zapewnia najlepszą metodę wykonywania zapytania, optymalizator zapytań używa indeksu w widoku. Ta funkcja jest nazywana indeksowanym widokiem zgodnym z. Przed programem SQL Server 2016 (13.x) z dodatkiem Service Pack 1 automatyczne używanie widoku indeksowanego przez optymalizator zapytań jest obsługiwane tylko w określonych wersjach programu SQL Server. W programie SQL Server 2016 (13.x) z dodatkiem Service Pack 1 lub nowszym wszystkie wersje obsługują automatyczne korzystanie z indeksowanego widoku. Usługi Azure SQL Database i Azure SQL Managed Instance obsługują również automatyczne korzystanie z indeksowanych widoków bez określania wskazówki NOEXPAND.

Aby uzyskać więcej informacji, zobacz Przewodnik po architekturze przetwarzania zapytań.

Aby uzyskać listę funkcji obsługiwanych przez wersje programu SQL Server w systemie Windows, zobacz:

Jednak aby optymalizator zapytań rozważył indeksowane widoki pod kątem dopasowania lub użyć indeksowanego widoku, do którego odwołuje się wskazówka NOEXPAND, należy ustawić następujące opcje SET na ON.

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

1ARITHABORT jest niejawnie ustawiona na ON po ustawieniu ANSI_WARNINGS na wartość ON. W związku z tym nie trzeba ręcznie dostosowywać tego ustawienia.

Ponadto należy ustawić opcję NUMERIC_ROUNDABORT na OFF.

Aby wymusić użycie indeksu dla widoku indeksowanego przez optymalizator zapytań, określ opcję NOEXPAND. Ta wskazówka może być używana tylko wtedy, gdy widok jest również nazwany w zapytaniu. Program SQL Server nie udostępnia wskazówek, aby wymusić użycie określonego indeksowanego widoku w zapytaniu, które nie nazywa widoku bezpośrednio w klauzuli FROM. Jednak optymalizator zapytań uwzględnia użycie widoków indeksowanych, nawet jeśli nie są one przywoływane bezpośrednio w zapytaniu. Aparat bazy danych programu SQL Server automatycznie tworzy statystyki tylko w widoku indeksowanym, gdy jest używana wskazówka tabeli NOEXPAND. Pominięcie tej wskazówki może prowadzić do ostrzeżeń planu wykonania dotyczących brakujących statystyk, których nie można rozwiązać, tworząc statystyki ręcznie.

Podczas optymalizacji zapytań aparat bazy danych używa statystyk widoku, które zostały utworzone automatycznie lub ręcznie, gdy zapytanie odwołuje się bezpośrednio do widoku, a wskazówka NOEXPAND jest używana.

Używanie wskazówki tabeli jako wskazówki dotyczącej zapytania

wskazówek tabeli można również określić jako wskazówkę zapytania przy użyciu klauzuli OPTION (TABLE HINT). Zalecamy użycie wskazówki tabeli jako wskazówki dotyczącej zapytania tylko w kontekście przewodnika planu . W przypadku zapytań ad hoc określ te wskazówki tylko jako wskazówki dotyczące tabeli. Aby uzyskać więcej informacji, zobacz Wskazówki dotyczące zapytań.

Uprawnienia

Wskazówki dotyczące KEEPIDENTITY, IGNORE_CONSTRAINTSi IGNORE_TRIGGERS wymagają ALTER uprawnień w tabeli.

Przykłady

A. Użyj wskazówki TABLOCK, aby określić metodę blokowania

Poniższy przykład określa, że udostępniona blokada jest wykonywana w tabeli Production.Product w bazie danych AdventureWorks2022 i jest przechowywana do końca instrukcji UPDATE.

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

B. Użyj wskazówki FORCESEEK, aby określić operację wyszukiwania indeksu

W poniższym przykładzie użyto wskazówki FORCESEEK bez określania indeksu, aby wymusić działanie optymalizatora zapytań w celu wykonania operacji wyszukiwania indeksu w tabeli Sales.SalesOrderDetail w bazie danych 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

W poniższym przykładzie użyto wskazówki FORCESEEK z indeksem, aby wymusić optymalizator zapytań wykonanie operacji wyszukiwania indeksu w określonej kolumnie indeksu i indeksu.

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. Użyj wskazówki FORCESCAN, aby określić operację skanowania indeksu

W poniższym przykładzie użyto wskazówki FORCESCAN, aby wymusić, że optymalizator zapytań wykona operację skanowania w tabeli Sales.SalesOrderDetail w bazie danych 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);