NOLOCK เลวเสมอหรือไม่


34

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

ตอนนี้ฉันทำงานกับ DBA ที่ถูกแบนไม่NOLOCKว่ากรณีใด ๆ - แม้ว่ารายงานของฉัน (เนื่องจากการขาดดัชนีจำนวนมากในตารางสองสามตาราง) กำลังหยุดการจำลองแบบและการอัปเดตระบบ ในความคิดของฉันในกรณีนี้NOLOCKจะเป็นสิ่งที่ดี

เนื่องจากการฝึกอบรม SQL ส่วนใหญ่ของฉันมาพร้อมกับ DBA ที่หลากหลายและมีความคิดเห็นที่แตกต่างกันมากฉันจึงอยากถามเรื่องนี้กับ DBA ที่หลากหลาย


1
อีกด้านหนึ่งของการสนทนานี้: dba.stackexchange.com/q/2684/2660
Nick Chammas

คำตอบ:


30

ถ้ามีการปรับปรุงบล็อกรายงานของคุณว่าคุณเป็น DBA ขวา: NOLOCKคุณควรอย่างยิ่งที่ได้ใช้ จริงอย่างที่มีมีความขัดแย้งเป็นข้อบ่งชี้ที่ชัดเจนว่าถ้าคุณจะใช้สกปรกอ่านคุณจะได้รับรายงานที่ไม่ถูกต้อง

ในความคิดของฉันมีทางเลือกที่ดีกว่าNOLOCK:

  • ตารางการผลิตของคุณมีการอ่านอย่างเดียวและไม่มีการแก้ไข? ทำเครื่องหมายฐานข้อมูลเป็นแบบอ่านอย่างเดียว!
  • การสแกนตารางทำให้เกิดความขัดแย้งกับล็อค? จัดทำดัชนีตารางอย่างเหมาะสมมีประโยชน์หลายประการ
  • ไม่สามารถแก้ไข / ไม่ทราบวิธีจัดทำดัชนีอย่างเหมาะสมหรือไม่ ใช้ภาพรวมแยก
  • ไม่สามารถเปลี่ยนแอปให้ใช้สแนปชอตได้หรือ เปิดสแน็ปช็อตที่อ่านแล้ว !
  • คุณวัดผลกระทบของการกำหนดเวอร์ชันของแถวและมีหลักฐานว่ามีผลกระทบต่อประสิทธิภาพหรือไม่ คุณไม่สามารถจัดทำดัชนีข้อมูลได้หรือ และคุณก็โอเคกับรายงานที่ไม่ถูกต้อง ? อย่างน้อยที่สุดคุณก็ทำสิ่งที่ชอบและใช้SET TRANSACTION ISOLATION LEVELไม่ใช่คำใบ้ จะง่ายกว่าในการแก้ไขระดับการแยกในภายหลังแทนที่จะแก้ไขทุกแบบสอบถาม

6
ระวัง: การเปิดสแนปชอตของการอ่านอาจทำให้รหัสบางอย่างเสียหาย
AK

33

มันไม่ได้เลวร้ายเสมอไป

แน่นอนมันช่วยให้คุณสามารถอ่านค่าที่ไม่มีข้อผูกมัด (ซึ่งอาจถูกย้อนกลับและไม่เคยมีอยู่ในเชิงตรรกะ) เช่นเดียวกับการอนุญาตให้ปรากฏการณ์เช่นค่าการอ่านหลาย ๆ ครั้งหรือไม่เลย

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

ปัญหาเหล่านี้มีแนวโน้มที่จะเกิดขึ้นภายใต้การnolockอย่างไรเพราะตามค่าเริ่มต้นที่ระดับแยกนี้มันจะใช้การจัดสรรได้รับคำสั่งสแกนเมื่อมันประมาณการมีมากกว่า 64 หน้าที่จะอ่าน เช่นเดียวกับหมวดหมู่ของปัญหาที่เกิดขึ้นเมื่อแถวย้ายไปมาระหว่างหน้าเนื่องจากการปรับปรุงคีย์ดัชนีการสแกนที่ได้รับคำสั่งการจัดสรรเหล่านี้ยังมีความเสี่ยงต่อปัญหาที่เกิดขึ้นกับการแยกหน้า (ที่สามารถพลาดแถวถ้าหน้าใหม่ สแกนแล้วหรืออ่านสองครั้งหากหน้าที่สแกนแล้วถูกแบ่งออกเป็นหน้าถัดไปในไฟล์)

อย่างน้อยสำหรับง่าย (ตารางเดียว) แบบสอบถามก็เป็นไปได้ที่จะกีดกันการใช้สแกนเหล่านี้และได้รับคีย์สั่งสแกนnolockโดยเพียงแค่การเพิ่มORDER BY index_keyการสืบค้นข้อมูลเพื่อให้Orderedทรัพย์สินของผู้เป็นIndexScantrue

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

แต่แน่นอนว่าคุณไม่ควรที่จะโยนมันลงไปในข้อความค้นหาทั้งหมดด้วยความหวังว่าจะเป็นปุ่ม "เทอร์โบ" เวทมนตร์ เช่นเดียวกับความน่าจะเป็นที่มากขึ้นของการพบผลลัพธ์ที่ผิดปกติในระดับการแยกหรือไม่มีผลลัพธ์เลย ("ไม่สามารถสแกน NOLOCK ต่อเนื่องจากข้อผิดพลาดการเคลื่อนไหวของข้อมูล") มีบางกรณีที่ประสิทธิภาพnolock อาจแย่ลงกว่าเดิม


3
+1 - เราใช้มันมากเพราะตารางการผลิตของเราไม่เคยได้รับการแก้ไข
JNK

@JNK คุณหมายถึงอะไรโดยไม่ได้รับการแก้ไข?
Kuberchaun

4
มาร์ตินฉันขอแนะนำคำที่แตกต่างกันเล็กน้อย: "ภายใต้ค่าที่อ่านได้แล้วอาจพลาดและอ่านได้มากกว่าหนึ่งครั้ง" เราสามารถเรียกดูแถวได้มากกว่าสองครั้งในบางกรณีที่แปลกใหม่
AK

@ StarShip3000 ข้อมูลที่เราปรับใช้กับการผลิตนั้นเป็นแบบอ่านอย่างเดียวสำหรับผู้ใช้ดังนั้นมุมมองของพวกเขาส่วนใหญ่จึงมีคำแนะนำ NOLOCK
JNK

11

ลูกค้าของคุณยอมรับผลที่ไม่สอดคล้องในรายงานหรือไม่ หากคำตอบคือไม่คุณไม่ควรใช้ NOLOCK - คุณสามารถรับผลลัพธ์ที่ผิดภายใต้การทำงานพร้อมกัน ผมเขียนไม่กี่ตัวอย่างที่นี่ , ที่นี่และที่นี่ ตัวอย่างเหล่านี้แสดงผลลัพธ์ที่ไม่สอดคล้องกันภายใต้ READ COMMITTED และ REPEATABLE READ แต่คุณสามารถปรับแต่งและรับผลลัพธ์ที่ไม่ถูกต้องด้วย NOLOCK


รายงานส่วนใหญ่ที่ฉันสร้างไม่ได้ทำงานกับข้อมูลปัจจุบัน ลูกค้าส่วนใหญ่ใช้รายงานเป็นข้อมูลของเมื่อวาน คำตอบของคุณจะเปลี่ยนแปลงหรือไม่ถ้าเป็นเช่นนั้น
DataGirl

8

รายงานส่วนใหญ่ที่ฉันสร้างไม่ได้ทำงานกับข้อมูลปัจจุบัน ลูกค้าส่วนใหญ่ใช้รายงานเป็นข้อมูลของเมื่อวาน คำตอบของคุณจะเปลี่ยนแปลงหรือไม่ถ้าเป็นเช่นนั้น

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

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

ฉันเป็นนักพัฒนาของฉันดังนั้นฉันจึงเป็นเรื่องง่ายเพราะฉันสามารถควบคุมเซิร์ฟเวอร์และฐานข้อมูลได้อย่างเต็มที่

คุณสามารถทำได้อย่างน้อยสำหรับรายงานที่ต้องการข้อมูลตั้งแต่เมื่อวานและเก่ากว่าเท่านั้น บางทีรายงานบางอย่างอาจต้องอยู่ในฐานข้อมูลการผลิต แต่อย่างน้อยคุณก็ย้ายบางส่วนของการโหลดไปยังฐานข้อมูลอื่น (หรือดีกว่าเซิร์ฟเวอร์อื่น)

ฉันมีสถานการณ์เดียวกันในที่ทำงานเช่นกัน:
เรากำลังใช้สำเนาฐานข้อมูลการผลิตเช่นนี้สำหรับเกือบทุกสิ่งที่รายงาน แต่มีข้อซักถามสองสามข้อที่ต้องใช้ข้อมูลของวันนี้


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