ฟิลด์“ นอกแถว” ถูกอ่านเมื่อใช้ดัชนีกลุ่มหรือไม่


10

ฉันรู้ว่าเมื่อVARCHAR(MAX)/NVARCHAR(MAX)มีการใช้คอลัมน์ข้อมูลจะถูกเก็บไว้out of the row- แถวข้อมูลจะมีตัวชี้ไปยังตำแหน่งอื่นที่จัดเก็บ 'ค่ามาก'

ฉันมีคำถามต่อไปนี้:

  1. อยู่ในแต่ละเขตข้อมูลที่เก็บไว้out of the rowหรือเพียงmaxคน?
  2. หากคุณกำลังใช้clustered indexตารางเพื่ออ่านระเบียนทั้งหมดเขตข้อมูลที่เก็บอยู่นอกแถวจะถูกอ่านด้วยหรือไม่

VARCHAR (MAX) หรือ NVARCHAR (MAX) ถือเป็น 'ประเภทค่าขนาดใหญ่' ประเภทค่าขนาดใหญ่มักจะเก็บไว้ที่ 'ออกจากแถว' มันหมายความว่า ...


2
บิตที่ยกมาล่าสุดนั้นมาจากไหน มันไม่ถูกต้อง
พอลไวท์ 9


3
ข้อความทั้งหมดในเธรด MSDN ดั้งเดิม (โดย Jacob Sebastian) ถูกต้อง Stack "Overflow" quote "สูญเสียไปเล็กน้อย ส่วนเล็ก ๆ ของที่คุณยกมาข้างต้นละเว้นทุกบิตที่สำคัญ :)
พอลไวท์ 9

คำตอบ:


13

ฉันรู้ว่าเมื่อVARCHAR(MAX)/NVARCHAR(MAX)มีการใช้คอลัมน์ข้อมูลจะถูกเก็บไว้นอกแถว ...

แต่จริงๆแล้วขึ้นอยู่กับการตั้งค่าของตัวเลือกซึ่งสามารถตั้งค่าการใช้large value types out of row sp_tableoptionจากเอกสารประกอบ :

สารสกัด BOL

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

ดังกล่าวเป็นแนวทางปฏิบัติที่ไม่ดีในการใช้MAXชนิดข้อมูลสำหรับค่าที่ไม่เกิน 8000 ไบต์ - ใช้ชนิดที่ไม่ใช่ MAX แทน นอกเหนือจากสิ่งอื่นแล้วประสิทธิภาพการทำงานมักด้อยลงเมื่อจัดการกับMAXชนิดเนื่องจาก SQL Server จะต้องเตรียมรับมือกับข้อมูลที่อาจมีขนาดใหญ่ถึง 2GB

แต่ละฟิลด์ถูกเก็บไว้นอกแถวหรือมีเพียงฟิลด์สูงสุดเท่านั้นหรือไม่

เฉพาะMAXคนที่ นอกจากนี้หากMAXคอลัมน์ในแถวก่อนหน้านี้ถูกย้ายออกไปแถวคอลัมน์เฉพาะในแถวนั้นจะได้รับผลกระทบ มันจะถูกแทนที่ในแถวโดยตัวชี้ไปยังLOBโครงสร้างปิดแถว นอกจากนี้ยังมีสถานการณ์ที่คอลัมน์ที่ไม่ใช่ MAX อาจถูกย้ายออกจากแถว

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

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


สิ่งนี้เป็นจริงเสมอScanning the clustered index traverses only in-row data.หรือไม่? ตัวอย่างเช่นหากคุณต้องการแสดงNVARCHAR(MAX)ค่าของเขตข้อมูลเป็นไปได้อย่างไรที่จะใช้งานได้เฉพาะกับin-row-data(หากค่าถูกเก็บไว้นอกแถว) หรือเมื่อคุณใช้ดัชนีคลัสเตอร์ (เพราะไม่มีดัชนีครอบคลุม) แต่คุณจะไม่ไปworkกับNVARCHAR(MAX)เขตข้อมูล SQL Server ฉลาดพอที่จะดูและข้ามไปดูout-of-rowข้อมูลหรือไม่
gotqn

ขอบคุณสำหรับคำตอบ. ดังนั้นในที่สุดถ้าคุณมีสองคอลัมน์ - intและnvarchar(max)และคุณจะเลือกเฉพาะintคอลัมน์ของ SQL เซิร์ฟเวอร์ไม่เสียทรัพยากรข้อมูลในขณะที่มันรู้ว่าคุณจะไม่ได้ไปใช้หรือไม่ readout-of-row
gotqn

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

3
@gotqn ใช่ ปิดแถวเป็นค่าเริ่มต้นสำหรับประเภทลอบเก่าtext, และntext imageคุณยังสามารถจัดเก็บประเภทขนาดใหญ่ในตารางแยกต่างหากแน่นอน
พอลไวท์ 9

4

พฤติกรรมนี้สำหรับการจัดเก็บวัตถุขนาดใหญ่สามารถควบคุมได้โดยการตั้งค่าตาราง:

exec sp_tableoption N'MyTable', 'large value types out of row', <'ON' or 'OFF'>

การอ้างอิงในเอกสารประกอบ SQL Server 2012 อยู่ที่: http://msdn.microsoft.com/en-us/library/ms173530.aspx

ดังนั้นคุณสามารถควบคุมตำแหน่งที่จะใช้พื้นที่ในแถวหรือเก็บออกจากแถว


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