ผลกระทบของคำใบ้ NOLOCK ในคำสั่ง SELECT


199

ฉันเดาคำถามจริงคือ:

หากฉันไม่สนใจเกี่ยวกับการอ่านที่สกปรกจะเพิ่มคำแนะนำด้วย (NOLOCK) ในคำสั่ง SELECT ที่มีผลต่อประสิทธิภาพของ:

  1. คำสั่ง SELECT ปัจจุบัน
  2. การทำธุรกรรมอื่น ๆ กับตารางที่กำหนด

ตัวอย่าง:

Select * 
from aTable with (NOLOCK)

3
คำตอบSOและDBAเหล่านี้มีความชัดเจนเล็กน้อยเกี่ยวกับสิ่งที่เกิดขึ้นจริง
ส่งเสียงเมื่อ

คำตอบ:


289

1) ใช่การเลือกด้วยNOLOCKจะเสร็จสมบูรณ์เร็วกว่าการเลือกปกติ

2) ใช่ตัวเลือกที่มีNOLOCKจะช่วยให้แบบสอบถามอื่น ๆ กับตารางที่ได้รับผลกระทบดำเนินการให้เร็วกว่าตัวเลือกปกติ

ทำไมถึงเป็นเช่นนี้?

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

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

คุณไม่มีทางรู้ว่าสถานะของข้อมูลคืออะไร

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

ใช้NOLOCKคำใบ้ด้วยความระมัดระวังอย่างยิ่งและรักษาข้อมูลใด ๆ ที่ส่งคืนอย่างน่าสงสัย


ขอบคุณ นี่คือสิ่งที่ฉันได้รับสมมติ แต่ถูกถามเกี่ยวกับเรื่องนี้โดยเพื่อนร่วมงานและการวิจัยครั้งแรกของฉันทำให้ฉันถามตัวเอง เอกสารคู่มือ SQLServer 2005 บอกว่าด้วย NOLOCK เป็นรูปแบบการล็อคเริ่มต้นสำหรับคำสั่งที่เลือกทั้งหมด! ฉันเดาแล้วว่าคำใบ้ของฉันจะเป็นสิ่งซ้ำซ้อนใน ...
Bob Probst

2
... 2005 และไม่มีผลกระทบใด ๆ เรากำลังใช้งาน 2000 ในตอนนี้ (ต้องขอบคุณผู้จำหน่ายของเรา) และไม่มีคำสั่งที่คล้ายกันในเอกสารประกอบ
Bob Probst

4
เพื่อนของคุณต้องอ่านเอกสาร ตารางคำใบ้ (Transact-SQL) msdn.microsoft.com/en-us/library/ms187373(SQL.90).aspx
Pittsburgh DBA

9
หมายเหตุด้านข้าง: ถ้านี่เป็นเรื่องจริงมันจะเป็นความสับสนวุ่นวาย
Pittsburgh DBA

1
จุดที่ 1 และ 2 จะต้องถูก จำกัด ที่ 1) "... เมื่อการกระทำแทรก / อัปเดต / ลบกำลังรอดำเนินการบนตาราง " และ 2) "... จะอนุญาตให้แทรก / อัปเดต / ลบข้อความค้นหาที่มีต่อ ... " ฉันต้องการ (การตั้งค่าส่วนตัว) เปลี่ยนอินสแตนซ์ของ "เร็ว" เป็น "เร็ว" เนื่องจากความแตกต่างกำลังรอกระบวนการอื่นให้เสร็จ
เดินขบวน

61

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

NOLOCK นั้นเทียบเท่ากับระดับการแยกของ READ UNCOMMITTED ความแตกต่างที่สำคัญคือคุณสามารถใช้ NOLOCK ในบางตาราง แต่ไม่ใช่อื่น ๆ หากคุณเลือก หากคุณวางแผนที่จะใช้ NOLOCK ในตารางทั้งหมดในแบบสอบถามที่ซับซ้อนแล้วการใช้ SET TRANSACTION ISOLATION LEOL ระดับการอ่าน UNCOMMITTED นั้นง่ายกว่าเพราะคุณไม่ต้องใช้คำใบ้กับทุกตาราง

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

ระดับการแยกธุรกรรมของตลาดหลักทรัพย์แห่งประเทศไทย

ตารางคำใบ้ (Transact-SQL)


2
ฉันเห็นด้วย แต่ไม่สมบูรณ์ เป็นสิ่งสำคัญที่จะต้องชี้ให้เห็นว่าคำใบ้ NO LOCK / READ UNCOMMITTED นั้นไม่ได้ปรับปรุงความเร็วของการสืบค้นจริง ๆ แต่ยิ่งทำให้มันปรากฏขึ้นเร็วขึ้นเพราะไม่ต้องรอให้การสืบค้นก่อนหน้านี้เสร็จสมบูรณ์ ดังนั้นจริง ๆ แล้วแบบสอบถาม SEEMS เร็วกว่าแทนที่จะเร็วขึ้น (ฉันคิดว่า)
Möoz

1
@BorhanMooz ดีมีเงินออมจากการไม่ต้องขอล็อคจากผู้จัดการล็อค แม้ว่าจะไม่มีคิวรีอื่น ๆ รออยู่ แต่ก็มีค่าใช้จ่ายและค่าใช้จ่ายในหน่วยความจำ
Pittsburgh DBA

1
ฉันคุยเรื่องนี้กับเพื่อนร่วมงานบางคนของฉัน ตามที่ฉันเข้าใจแล้วแบบสอบถามที่ใช้คำแนะนำ WITH (NOLOCK) ยังต้องมีการล็อคการแชร์ Schema ( mssqltips.com/sqlservertip/2470/… )
Möoz

1
ใช่ แต่ไม่ใช่การล็อคที่ใช้ร่วมกันนับพันรายการในหน้าหรือขอบเขต ล็อคสคีมาเป็นหนึ่งล็อคไม่นับพัน หากเราต้องการอวดความรู้เราสามารถอภิปรายเรื่องนี้ต่อไปได้ แต่ใช่จะมีค่าใช้จ่ายการล็อคจำนวนเล็กน้อย การออมมีความสำคัญ ทำคณิตศาสตร์ในเรื่องนี้: msdn.microsoft.com/en-us/library/aa337559(v=sql.100).aspx
Pittsburgh DBA

14

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

ดูhttp://blogs.msdn.com/sqlcat/archive/2007/02/01/previously-committed-rows-might-be-missed-if-nolock-hint-is-used.aspx


6

มันจะเร็วขึ้นเพราะไม่ต้องรอการล็อค


เร็วแค่ไหน คุณสามารถระบุหมายเลขการปรับปรุงความเร็วได้หรือไม่
Eugeniu Torica

5
"เท่าใด" ขึ้นอยู่กับสิ่งที่คุณทำกับข้อมูลของคุณโดยเฉพาะและระยะเวลาที่คุณต้องรอการได้รับล็อค
StingyJack

เกณฑ์มาตรฐานที่ถูกต้องเพียงอย่างเดียวคือสิ่งที่คุณสร้างและดำเนินการ สิ่งที่ทุกคนบอกคุณดีเท่ากับ "เช็คอยู่ในเมล" ฉันได้พิสูจน์มายาคติและข้อสันนิษฐานผิดหลายครั้งด้วยการใช้การวัดประสิทธิภาพของตัวเอง
TravisO

^ @TravisO - ถูกต้องสมบูรณ์ ฉันเคย NOLOCK รันช้าลงสองสามครั้ง ไม่แน่ใจว่าทั้งหมดว่าทำไม แต่ผมใช้ว่าเมื่อการแก้ไขปัญหาและฉันไม่ต้องการที่จะในเชิงลบ (กว่า) ส่งผลกระทบต่อการผลิต
StingyJack

2
  • คำตอบคือใช่ถ้ามีการเรียกใช้แบบสอบถามหลายครั้งพร้อมกันเนื่องจากแต่ละธุรกรรมไม่จำเป็นต้องรอให้รายการอื่นดำเนินการจนเสร็จ อย่างไรก็ตามหากแบบสอบถามถูกเรียกใช้เพียงครั้งเดียวคำตอบคือไม่

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

ระวังให้ใช้เฉพาะWITH (NOLOCK)ในคำสั่ง SELECT บนตารางที่มีดัชนีคลัสเตอร์

ด้วย (NOLOCK) มักถูกใช้เป็นวิธีที่วิเศษในการเพิ่มความเร็วในการอ่านธุรกรรม

ชุดผลลัพธ์สามารถมีแถวที่ยังไม่ได้ส่งซึ่งมักจะย้อนกลับในภายหลัง

หาก WITH (NOLOCK) ถูกนำไปใช้กับตารางที่มีดัชนีที่ไม่ใช่คลัสเตอร์ดังนั้นดัชนีแถวสามารถเปลี่ยนแปลงได้โดยธุรกรรมอื่น ๆ เนื่องจากข้อมูลแถวกำลังถูกสตรีมเข้าสู่ตารางผลลัพธ์ ซึ่งหมายความว่าชุดผลลัพธ์อาจหายไปแถวหรือแสดงแถวเดียวกันหลายครั้ง

READ COMMITTED เพิ่มปัญหาเพิ่มเติมที่ข้อมูลเสียหายภายในคอลัมน์เดียวที่ผู้ใช้หลายคนเปลี่ยนเซลล์เดียวกันพร้อมกัน

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