Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Основи и използване на NOLOCK намек в SQL Server

Основната идея на механизма за заключване на SQL Server е, че той контролира последователността на транзакциите. Съгласно този принцип, ако даден процес иска да извърши операции за вмъкване, изтриване или актуализиране, SQL Server двигателят заключва реда или редовете и не позволява друг процес, докато транзакцията не бъде завършена. При някои обстоятелства този заключващ механизъм може да доведе до проблеми с производителността, като например високо едновременно налягане на процеса. Така че можете да се сблъскате с проблемите със застой (Deadlock е проблем с паралелност, при който две транзакции искат да имат достъп до едни и същи данни едновременно) проблеми във вашата база данни. В тази статия ще се съсредоточим върху това как да избегнем проблеми със заключване с помощта на NOLOCK намек. Първо, нека научим основните неща и подробности за методологията за мръсно четене, защото намекването NOLOCK може да причини мръсно четене.

Мръсно четене: В тази методология на четене процесът на четене чете незаети данни и процесът на четене не се интересува от отворени транзакции, така че заключванията не водят до проблеми в процеса на четене. В резултат на това този тип четене намалява проблемите със заключването. Въпреки това методологията на мръсното четене има плюсове и минуси, тъй като мръсното четене може да причини проблеми с несъответствието в набора от резултати на оператора SELECT. Както вече беше отбелязано, тези набори от резултати могат да включват данни за незаети транзакции, ето защо трябва да вземем предвид мръсното четене, когато решаваме да направим този вид четене. Не можем да сме сигурни в точността на редовете, които правим по време на мръсно четене, защото тези редове могат да бъдат връщани назад. От друга страна, този тип четене ни позволява да избегнем проблеми със заключването и да увеличим производителността на SQL Server.

NOLOCK: Нивото на изолация на SQL Server по подразбиране е Read Committed и в това ниво на изолация SQL Server не позволява четене на заключени обекти, които са заключени от незаети транзакции. Освен това тези заключени обекти могат да се променят според ескалацията на заключването.

Забележка:В тази статия Основна концепция за заключването на SQL Server можете да намерите подробности за заключването и ескалацията на заключването.

Представете си, че имате двама потребители на база данни и тези потребители искат да изпълнят актуализация и да изберат операция срещу базата данни. Първият потребител започва да актуализира конкретен ред в таблицата и след това другият потребител иска да прочете същия ред. Тези двама потребители изпълняват следната актуализация и селектиране, което е илюстрирано на изображението по-долу.

В този случай user2 изчаква най-малко 10 секунди и след това транзакцията ще бъде върната от потребител1, а след това user2 може да прочете зеления ред, защото заключеният ред ще бъде освободен от user1. Това е поведението по подразбиране на нивото на изолация на SQL Server Read Committed.

Сега ще демонстрираме този случай в SQL Server. Първо, ще създадем таблицата FruitSales и нейните редове.

СЪЗДАВАНЕ НА ТАБЛИЦА FruitSales(Id INT IDENTITY (1,1) PRIMARY KEY, [Име] Varchar(20) ,SalesTotal Float)GOINSERT INTO FruitSales VALUES('Apple',10) ,('Orange',8), ( „Банан“, 2)

В тази стъпка ще отворим два прозореца за заявка на SQL Server Management Studio и ще изпълним заявката user1 и след това ще изпълним заявката user2.

 ---USER1----ЗАПОЧНЕТЕ АКТУАЛИЗИРАНЕ НА TRAN FruitSales SET SalesTotal =20 WHERE Id=2 WAITFOR DELAY '00:00:10'ROLLBACK TRANSACTION ---USER2----ЗАДАДЕТЕ ВРЕМЕ НА СТАТИСТИКА ONSELECT * ОТ FruitSales КЪДЕ Id=2

Както можете да видите на изображението по-горе, втората заявка изчаква до отмяната на транзакцията user1.

Сега ще обсъдим съвета и подробностите за употребата на NOLOCK. Подсказката NOLOCK е най-популярният съвет за таблица, който се използва от разработчиците на бази данни и администраторите за премахване на проблеми със заключването в базите данни на SQL Server. С помощта на подсказката на таблицата NOLOCK можем да четем заключени обекти (ред, страница или таблица), които са заключени от отворени транзакции. Подсказката NOLOCK отменя поведението по подразбиране на оптимизатора на заявки на SQL Server, така че операторът select да може да чете заключените обекти.

Сега ще добавим подсказката NOLOCK към оператора user2 select и след това ще стартираме актуализацията на user1 и след това ще изпълним оператора user2 select.

---USER1----ЗАПОЧНЕТЕ АКТУАЛИЗИРАНЕ НА TRAN FruitSales SET SalesTotal =20 WHERE Id=2 WAITFOR DELAY '00:00:10'ОТМЕНЯНЕ НА ТРАНЗАКЦИЯ ---USER2----ЗАДАДЕТЕ ВРЕМЕ НА СТАТИСТИКА НА ИЗБОР * ОТ FruitSales С (NOLOCK) WHERE Id=2

В тази стъпка ще обясним как да повлияем на подсказката NOLOCK върху оператора user2 select. User1 изпълнява актуализирания израз в изрична транзакция и след това user2 изпълнява оператора select и резултатният набор връща без забавяне завършването на транзакцията. Това е основната идея на NOLOCK, той чете заключени обекти.

Сега ще се съсредоточим върху набора от резултати на оператора select. Инструкцията user2 select извлече стойността SalesTotal 20, но действителната стойност на SalesTotal все още е 8. Имайте предвид, че ако използвате подсказката за таблицата NOLOCK в оператора за избор, може да се сблъскате с този тип неточни резултати от данни.

Съвет: Ключовата дума „WITH“ е отхвърлена функция, така че Microsoft препоръчва да не я използвате при разработката на новата си база данни и да премахнете ключовата дума „WITH“ в текущите си разработки. Можете да намерите използването на подсказката NOLOCK без ключова дума „WITH“.

---USER1----ЗАПОЧНЕТЕ АКТУАЛИЗИРАНЕ НА TRAN FruitSales SET 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

Освен това подсказката за таблица READUNCOMMITTED е еквивалентна на подсказката NOLOCK и можем да използваме намека READUNCOMMITTED вместо намека NOLOCK.

ИЗБЕРЕТЕ * ОТ FruitSales (READUNCOMMITTED) КЪДЕТО Id=2

Въпреки това има конкретен случай за намек за NOLOCK, който не може да премине през заключващата бариера. Ако има някакъв процес, променящ таблица, подсказката NOLOCK не може да преодолее този тип заключване и не може да продължи операцията за четене. Причината за този проблем е, че подсказката NOLOCK придобива заключването Sch-S (стабилност на схемата), а операторът ALTER TABLE придобива заключването SCH-M (модификация на схема), така че възниква конфликт.

Първо ще научим Object_Id на таблицата FruitSales с помощта на следната заявка.

изберете OBJECT_ID('FruitSales')

Изпълнете следната заявка user1 и след това изпълнете заявката user2. В резултат на това заявката user2 ще забави завършването на процеса на промяна на таблицата user1.

--USER1---BEGIN TRANALTER TABLE FruitSalesADD ColorofFruit varchar(200) WAITFOR DELAY '00:00:35GOCOMMIT TRAN --USER2---SELECT * ОТ FruitSales (NOLOCK) WHERE Id=2

Отворете новия прозорец за заявка и изпълнете следната заявка. Тази заявка ще ви помогне да разберете типа заключване на заявките user1 и 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_type, Request_owner_type, Request_owner_type, Request_owner_type, Request_owner_type, Request_owner_type, Request_owner_type, Request_owner_id, Request_owner_id, Request_owner_id_56 Request_owner_ysdm_where. 

Сега ще проверим матрицата за съвместимост на заключване за взаимодействието SCH-M и SCH-S. Матрицата описва, че взаимодействието SCH-M и SCH-S причинява конфликт.

Заключение

В тази статия споменахме процеса на мръсно четене и намек за NOLOCK. Използването на подсказката NOLOCK е ефективен метод за четене на заключена страница, но също така има някои предимства и недостатъци. Поради тази причина трябва да вземете предвид съвета NOLOCK, преди да го използвате.

Препратки

Ръководство за заключване на транзакции на SQL Server и версия на ред

Съвети (Transact-SQL) – Таблица

ЗАДАЙТЕ НИВО НА ИЗОЛАЦИЯ НА ТРАНЗАКЦИЯТА (Transact-SQL)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 3 начина да получите схемата на набор от резултати в SQL Server

  2. Неочаквано поведение @@rowcount в UDF в MS SQL 2019

  3. Има ли начин да преминете през променлива на таблица в TSQL, без да използвате курсор?

  4. Премахване на дублиращи се редове (въз основа на стойности от множество колони) от SQL таблица

  5. Използване на пълнотекстово търсене в SQL Server 2008 в множество таблици, колони