สถานการณ์ที่ดีที่สุดในการใช้ระดับการแยก READ UNCOMMITTED


10

ดังที่เราทุกคนทราบกันดีว่าการอ่านไม่ได้รับการยอมรับนั้นเป็นระดับการแยกต่ำสุดที่สิ่งต่าง ๆ เช่นการอ่านสกปรกและการอ่าน phantom อาจเพิ่มขึ้น เวลาที่ดีที่สุดในการใช้ระดับการแยกนี้เมื่อใดและด้วยเหตุผลใดบ้างที่ควรใช้

ที่จริงฉันอ่านคำตอบก่อนหน้านี้ แต่ฉันไม่สามารถเข้าใจได้อย่างสมบูรณ์เพราะมีตัวอย่างไม่เพียงพอ

คำตอบ:


20

ฉันใช้READ_UNCOMMITTED(หรือNOLOCK) เมื่อสอบถามฐานข้อมูลการผลิตจาก SSMS แต่ไม่ได้เป็นประจำจากรหัสแอปพลิเคชัน การปฏิบัตินี้ (พร้อมด้วยคำแนะนำการค้นหา MAXDOP 1) ช่วยให้มั่นใจได้ว่าแบบสอบถามแบบไม่เป็นทางการสำหรับการวิเคราะห์ข้อมูลและการแก้ไขปัญหาจะไม่ส่งผลกระทบต่อปริมาณการผลิตเนื่องจากการเข้าใจว่าผลลัพธ์อาจไม่ถูกต้อง

น่าเศร้าที่ฉันเห็นREAD_UNCOMMITTED/ NOLOCKใช้กันอย่างแพร่หลายในรหัสการผลิตเพื่อหลีกเลี่ยงการปิดกั้นค่าใช้จ่ายของความสมบูรณ์ของข้อมูล ทางออกที่เหมาะสมคือระดับการแยกแถวเวอร์ชัน ( SNAPSHOTหรือREAD_COMMITTEDด้วยREAD_COMMITTED_SNAPSHOTตัวเลือกฐานข้อมูลON) และ / หรือความสนใจในการค้นหาและปรับดัชนี

ฉันเพิ่งได้รับการตรวจสอบรหัส proc ซึ่งการเปลี่ยนแปลงเพียงอย่างเดียวคือการลบNOLOCKเพราะบางครั้งก็ส่งคืนผลลัพธ์ที่ผิด การลบออกNOLOCKเป็นสิ่งที่ดี แต่เมื่อรู้ว่ามักจะพลาดหรือทำซ้ำแถวเกิดขึ้นระหว่างการสแกนคำสั่งการจัดสรรของตารางขนาดใหญ่ฉันแนะนำให้ทำการปรับโครงสร้างใหม่เพื่อใช้UNION ALLเทคนิคเพื่อส่งเสริมการใช้ดัชนีอย่างมีประสิทธิภาพ ตอนนี้แบบสอบถามจะทำงานในเวลาไม่กี่มิลลิวินาทีโดยมีผลลัพธ์ที่ถูกต้องซึ่งเป็นสิ่งที่ดีที่สุดในโลก


7

ฉันคิดว่ามันใช้ได้ในบางสถานการณ์ตราบใดที่คุณยอมรับผลที่ตามมาและไม่มีทางเลือกอื่น

สำหรับตัวเลือกอื่น ๆ ฉันจะผลักดันให้ผู้ใช้ใช้ Read Committed Snapshot Isolation (RCSI) สำหรับแอปพลิเคชันใหม่หรือ SNAPSHOT ISOLATION (SI) สำหรับแอปพลิเคชันรุ่นเก่าซึ่งคุณไม่สามารถทดสอบฐานรหัสทั้งหมดสำหรับสภาพการแข่งขันด้วย RCSI ได้อย่างง่ายดาย

อย่างไรก็ตามสิ่งเหล่านั้นอาจไม่เหมาะสม คุณอาจต้องใช้เวลาพิเศษในการรักและดูแล tempdb และต้องแน่ใจว่าไม่มีใครเหลือธุรกรรมที่เปิดอยู่ซึ่งทำให้ที่เก็บรุ่น (และ tempdb) เติบโตและเติมดิสก์

หากคุณไม่มี DBA หรือบุคคลที่มีหน้าที่ดูแลและจัดการ SQL Server ของคุณตัวเลือกเหล่านั้นอาจเป็นอันตรายได้ โดยทั่วไปทุกคนไม่สามารถควบคุมรหัสทั้งหมดไปยังเซิร์ฟเวอร์ของพวกเขาซึ่งพวกเขาสามารถเปลี่ยนสตริงการเชื่อมต่อหรือรหัสเพื่อขอ SI สำหรับการสอบถามปัญหา

นอกจากนั้นคนส่วนใหญ่ไม่ได้มีปัญหากับการล็อคของพวกเขาโปรแกรมทั้งหมด พวกเขามีปัญหากับสิ่งต่าง ๆ เช่นการรายงานข้อมูล OLTP หากคุณสามารถยอมรับการแลกเปลี่ยน NOLOCK / RU เพื่อแลกเปลี่ยนรายงานที่ไม่ได้ถูกบล็อกโดยนักเขียน

เพียงให้แน่ใจว่าคุณเข้าใจความหมาย ไม่ได้หมายความว่าคิวรีของคุณไม่ได้ล็อค แต่ก็ไม่ได้หมายความว่าล็อคไม่ได้รับการล็อคจากการสืบค้นอื่น ๆ

และแน่นอนถ้าปัญหาของคุณคือล็อคนักเขียน / นักเขียนตัวเลือกเดียวที่จะช่วยได้ก็คือ SI แต่มันต้องใช้จำนวนงานที่ไม่น่าเชื่อของนักพัฒนาที่จะใช้งานอย่างถูกต้องด้วยการจัดการข้อผิดพลาด ฯลฯ


5
และหากปัญหานั้นเป็นเพียงการรายงานข้อมูลของ OLTP ให้ทำการลดขนาดนั้นลงในส่วนรองแบบอ่านอย่างเดียวบางประเภท (AG, บันทึกการจัดส่ง, การจำลองหรือม้วนตัวคุณเอง)
Aaron Bertrand

3
@AaronBertrand จากนั้นพวกเขามีเซิร์ฟเวอร์ตัวที่สองเพื่อตรวจสอบ;)
Erik Darling

5

IMHO กรณีการใช้งานที่ถูกต้องเพียงอย่างเดียวสำหรับ READ UNCOMMITTED บนระบบที่ทันสมัยคือเมื่อทำการดีบั๊กเซสชันหนึ่งจากอีกอันหนึ่งในการพัฒนาดังนั้นคุณสามารถเห็นสิ่งที่กำลังทำอยู่ขณะที่ proc ที่เก็บไว้ยังคงทำงานอยู่ มันจะไม่ถูกใช้ตามปกติในระบบการผลิต อาจมีการเพิ่มประสิทธิภาพเล็กน้อย แต่ในระยะยาวจะไม่คุ้มค่า


3

เราใช้มันในการดูแลสุขภาพตลอดเวลา

มันเป็นเรื่องยากอย่างน่าประหลาดใจสำหรับแถวข้อมูลแต่ละแถวที่จะเปลี่ยนการสืบค้นกลางและอัตราส่วนการอ่าน / เขียนเท่ากับ 10,000 / 1 - และส่วนใหญ่เป็นการแทรกไม่ใช่การปรับปรุง ตัวอย่างเช่นเมื่ออินเตอร์เฟสของแล็บเขียนผลลัพธ์ของแล็บของผู้ป่วยลงในฐานข้อมูลค่าเหล่านั้นจะไม่เปลี่ยนแปลง

เมื่อข้อมูลไม่เปลี่ยนแปลงจะเปลี่ยนหนึ่งแถวในเวลา ไม่มีใครอัปเดตคอลัมน์ทั้งหมด (ยกเว้น DBA เมื่อพวกเขาทำไม่ดีจริงๆ)

ในอีกด้านหนึ่งเราเรียกใช้แบบสอบถามจำนวนมากเพื่อสแกนหาสิ่งต่าง ๆ เช่นผู้ป่วยกลับมาที่ ER ใน 72 ชั่วโมงหรือน้อยกว่าซึ่งส่งผลเสียต่อตารางอย่างแน่นอน

ในปีที่ 10 ของการดูแลสุขภาพ SQL Rollback Transactionผมไม่เคยเห็น ฉันต้องการเข้าและออกโดยไม่รบกวนประสบการณ์ของผู้ใช้ หากมีความเสี่ยงสูงในการชะลอฐานข้อมูล OLTP และความเสี่ยงต่ำในการรับข้อมูลที่ไม่ดีฉันจะ NOLOCK

เราควรใช้มันหรือไม่? อาจจะอาจจะไม่. โดยทั่วไปแล้วฉันจะไม่พูดว่าฐานข้อมูลแอปพลิเคชันจำนวนมากที่ฉันได้ออกแบบมานั้นดี พวกเขามักจะหนุนเต็มรูปแบบของการต่อต้าน


4
เพียง FYI ก็เป็นไปได้ที่จะอ่านแถวที่เขียนบางส่วนด้วย nolock
Max Vernon

1
OOF! ฉันต้องการให้เจ้านายของฉันซื้อเซิร์ฟเวอร์อื่นให้ฉันเพื่อที่ฉันจะได้จัดส่งสิ่งของนี้ได้ ....
James

3
คุณอาจสนใจโพสต์บล็อกที่ดีนี้จาก Paul White เกี่ยวกับ READ UNCOMMITTED โดยเฉพาะส่วน "Reading Corrupt Data": ระดับการอ่านแยกที่ไม่มีข้อผูกมัด
Josh Darnell

1

READ_UNCOMMITTED/NOLOCKเป็นตัวเลือกที่ดีเมื่อความถูกต้องของข้อมูลไม่ใช่เป้าหมายหลักจริงๆ บางครั้งเมื่อมีการนับรวมทั้งหมดเป็นสิ่งที่จำเป็น ตัวอย่างเช่น: มีกระบวนงานที่เก็บไว้ซึ่งใช้กับทั้งตาราง INSERT หรือ UPDATE บางครั้งจำนวนของระเบียนที่จะปรับปรุงหรือแทรกมีขนาดใหญ่มาก (หลายพันระเบียน) ช่วงนี้เก็บขั้นตอนการทำงานเราสามารถเรียกใช้แบบสอบถามเลือกที่เรียบง่ายด้วยNOLOCKบนโต๊ะเป้าหมายเป็นระยะ ๆ เพื่อดูว่ามันจะดำเนินไปได้อย่างราบรื่น (สอบถามปรับปรุงถ้าคุณมีคอลัมน์เปลี่ยนสถานะสำหรับบันทึกการปรับปรุงที่เราสามารถใช้คอลัมน์ที่รันgroup byแบบสอบถามNOLOCKเพื่อค้นหาว่าจำนวนการเปลี่ยนแปลงสถานะเปลี่ยนแปลงตลอดเวลาหรือไม่)


0

โปรดทราบว่าการอ่านไม่ได้รับการแนะนำจะนำเสนอปัญหาที่สอดคล้องกันเพิ่มเติมไม่ใช่แค่อ่านสกปรก ขึ้นอยู่กับวิธีการเข้าถึงคุณอาจพลาดแถวหรือแม้แต่อ่านแถวเดียวกันมากกว่าหนึ่งครั้ง หากคุณมีความสนใจในรายละเอียดอ่านบทความของItzik Ben-Gan


3
แถวที่ขาดหายไปและการอ่านแถวมากกว่าหนึ่งครั้งเป็นไปได้ที่ค่าเริ่มต้นระดับการอ่านที่กำหนดเช่นกัน หากคอลัมน์คีย์ดัชนีได้รับการปรับปรุงในระหว่างการสแกนและมันจะย้าย
Martin Smith

อภิปราย Side ได้คำตอบนี้ได้รับการย้ายไปแชท
พอลไวท์ 9
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.