sql >> Databáze >  >> RDS >> Sqlserver

Základy a použití nápovědy NOLOCK v SQL Server

Hlavní myšlenkou zamykacího mechanismu SQL Server je, že řídí konzistenci transakcí. Podle tohoto principu, pokud chce proces provést operace vložení, odstranění nebo aktualizace, stroj SQL Server uzamkne řádek nebo řádky a nepovolí další proces, dokud není transakce dokončena. Za určitých okolností může tento uzamykací mechanismus vést k problémům s výkonem, jako jsou vysoké souběžné procesní tlaky. Takže můžete zaznamenat problémy se zablokováním (zablokování je problém souběžnosti, kdy dvě transakce chtějí přistupovat ke stejným datům současně) ve vaší databázi. V tomto článku se zaměříme na to, jak se vyhnout problémům se zámkem pomocí nápovědy NOLOCK. Nejprve se naučíme hlavní základy a podrobnosti metodologie nečistého čtení, protože nápověda NOLOCK může způsobit nečisté čtení.

Nečisté čtení: V této metodice čtení čte proces čtení nepotvrzená data a proces čtení se nestará o otevřené transakce, takže zámky nevedou k žádným problémům v procesu čtení. Výsledkem je, že tento typ čtení snižuje problémy se zamykáním. Metodika nečistého čtení má však klady a zápory, protože nečisté čtení může způsobit problémy s nekonzistencí ve výsledné sadě příkazu SELECT. Jak již bylo uvedeno, tyto sady výsledků mohou obsahovat data o nepotvrzených transakcích, proto musíme při rozhodování o provedení tohoto druhu čtení vzít v úvahu nečisté čtení. Nemůžeme si být jisti přesností řádků, které děláme při nečistém čtení, protože tyto řádky lze vrátit zpět. Na druhou stranu nám tento typ čtení umožňuje vyhnout se problémům se zamykáním a zvýšit výkon SQL Serveru.

NOLOCK: Výchozí úroveň izolace SQL Serveru je Číst potvrzeno a v této úrovni izolace SQL Server neumožňuje číst uzamčené objekty, které jsou uzamčeny nepotvrzenými transakcemi. Tyto zamčené objekty lze navíc měnit podle eskalace zámku.

Poznámka:V tomto článku Hlavní koncepce zamykání serveru SQL Server naleznete podrobnosti o zamykání a eskalaci uzamčení.

Představte si, že máte dva uživatele databáze a tito uživatelé chtějí provést aktualizaci a vybrat operaci proti databázi. První uživatel začne aktualizovat konkrétní řádek v tabulce a poté chce druhý uživatel číst stejný řádek. Tito dva uživatelé provedou následující aktualizaci a vyberou příkazy, což je znázorněno na obrázku níže.

V tomto případě uživatel2 čeká alespoň 10 sekund a poté bude transakce uživatelem1 odvolána a poté uživatel2 může číst zelený řádek, protože zamčený řádek bude uvolněn uživatelem1. Toto je výchozí chování úrovně izolace SQL Server Read Committed.

Nyní předvedeme tento případ na SQL Serveru. Nejprve si vytvoříme tabulku FruitSales a její řádky.

VYTVOŘIT TABULKU FruitSales(Id INT IDENTITY (1,1) PRIMÁRNÍ KLÍČ, [Název] Varchar(20) ,SalesTotal Float)GOINSERT INTO FruitSales VALUES('Apple',10) ,('Orange',8), ( 'Banán',2)

V tomto kroku otevřeme dvě okna dotazu SQL Server Management Studio a provedeme dotaz user1 a poté spustíme dotaz user2.

 ---USER1----ZAČÁTE AKTUALIZOVAT SADA FruitSales SalesTotal =20 WHERE Id=2 WAITFOR DELAY '00:00:10'ROLLBACK TRANSAKCE ---USER2----SET STATISTICS TIME ONSELECT * FROM FruitSales WHERE Id=2

Jak můžete vidět na obrázku výše, druhý dotaz čeká na vrácení zpět transakce user1.

Nyní budeme diskutovat o radě NOLOCK a podrobnostech o použití. Nápověda NOLOCK je nejoblíbenější nápověda k tabulce, kterou používají vývojáři a správci databází k odstranění problémů se zámkem v databázích SQL Server. Pomocí nápovědy tabulky NOLOCK můžeme číst zamčené objekty (řádek, stránka nebo tabulka), které jsou uzamčeny otevřenými transakcemi. Nápověda NOLOCK přepíše výchozí chování optimalizátoru dotazů SQL Server, takže příkaz select může číst uzamčené objekty.

Nyní do příkazu user2 select přidáme nápovědu NOLOCK a poté spustíme aktualizaci user1 a poté provedeme příkaz user2 select.

---USER1----ZAČÁTEK AKTUALIZACE SADA FruitSales SalesTotal =20 WHERE Id=2 WAITFOR DELAY '00:00:10'ROLLBACK TRANSAKCE ---USER2----SET STATISTICS TIME ONSELECT * Z FruitSales WITH (NOLOCK) WHERE Id=2

V tomto kroku vysvětlíme, jak ovlivnit nápovědu NOLOCK na příkaz user2 select. Uživatel1 provede aktualizovaný příkaz v explicitní transakci a potom uživatel2 provede příkaz select a sada výsledků bez zpoždění vrátí dokončení transakce. To je hlavní myšlenka NOLOCK, čte zamčené objekty.

Nyní se zaměříme na sadu výsledků příkazu select. Příkaz select user2 načetl hodnotu SalesTotal 20, ale skutečná hodnota SalesTotal je stále 8. Mějte na paměti, že pokud ve svém příkazu select používáte nápovědu tabulky NOLOCK, můžete čelit tomuto typu nepřesných datových výsledků.

Tip: Klíčové slovo „WITH“ je zastaralá funkce, takže společnost Microsoft doporučuje nepoužívat je při vývoji nové databáze a odstranit klíčové slovo „WITH“ ze stávajícího vývoje. Použití nápovědy NOLOCK můžete najít bez klíčového slova „WITH“.

---USER1----ZAČÁTEK AKTUALIZACE SADA FruitSales SalesTotal =20 WHERE Id=2 WAITFOR DELAY '00:00:10'ROLLBACK TRANSACTIONSELECT * FROM FruitSales WHERE Id=2 --USER2---SELECT * FROM FruitSales (NOLOCK) WHERE Id=2

Kromě toho je nápověda tabulky READUNCOMMITTED ekvivalentní nápovědě NOLOCK a místo nápovědy NOLOCK můžeme použít nápovědu READUNCOMMITTED.

VYBERTE * Z FruitSales (PŘEČTĚTE NEZÁVAZNĚNO) KDE Id=2

I tak existuje zvláštní případ s nápovědou NOLOCK, která nemůže projít uzamykací bariérou. Pokud dojde k nějakému procesu, který mění tabulku, nápověda NOLOCK nemůže tento typ zámku překonat a nemůže pokračovat v operaci čtení. Důvodem tohoto problému je, že nápověda NOLOCK získává zámek Sch-S (stabilita schématu) a příkaz ALTER TABLE získává zámek SCH-M (úprava schématu), takže dochází ke konfliktu.

Nejprve se pomocí následujícího dotazu naučíme Object_Id tabulky FruitSales.

vyberte OBJECT_ID('FruitSales')

Spusťte následující dotaz uživatel1 a potom spusťte dotaz uživatel2. V důsledku toho dotaz user2 zpozdí dokončení procesu změny tabulky user1.

--USER1---ZAČÁTE TRANALTER TABLE FruitSalesADD ColorofFruit varchar(200) WAITFOR DELAY '00:00:35GOCOMMIT TRAN --USER2---SELECT *FROM FruitSales (NOLOCK) WHERE Id=2

Otevřete okno nového dotazu a proveďte následující dotaz. Tento dotaz pomůže zjistit typ zámku dotazů user1 a user2.

SELECT Resource_type, Resource_database_id, Resource_description, Resource_associated_entity_id, Resource_lock_partition, Request_mode, Request_type, Request_status, Request_session_id, Request_request_id, Request_owner_type, Request_owner_addressent, kdekolidF5ROM_ownerci7 systranslock3 resource_asso_67 

Nyní se podíváme na matici kompatibility zámku pro interakci SCH-M a SCH-S. Matice popisuje, že interakce SCH-M a SCH-S způsobuje konflikt.

Závěr

V tomto článku jsme zmínili proces špinavého čtení a nápovědu NOLOCK. Použití nápovědy NOLOCK je efektivní způsob čtení zamčené stránky, ale má také některé výhody a nevýhody. Z tohoto důvodu musíte před použitím zvážit nápovědu NOLOCK.

Odkazy

Příručka zamykání transakcí serveru SQL a verzování řádků

Rady (Transact-SQL) – Tabulka

NASTAVTE ÚROVEŇ IZOLACE TRANSAKCE (Transact-SQL)


  1. Použití Oracle JDeveloper s databázovou službou MySQL na platformě Oracle Cloud, část 3

  2. Proč se pg_restore úspěšně vrací, ale ve skutečnosti neobnovuje moji databázi?

  3. Proč ISNUMERIC('.') vrací 1?

  4. Datum v adrese URL dd/mm/rrrr