สถานการณ์การใช้งานที่ถูกต้องสำหรับตาราง HEAP คืออะไร


31

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

เท่าที่ฉันเข้าใจตาราง HEAP จะมีประโยชน์สำหรับตารางการตรวจสอบและ / หรือตำแหน่งที่แทรกเกิดขึ้นบ่อยกว่าการเลือก มันจะประหยัดพื้นที่ดิสก์และดิสก์ I / O เนื่องจากไม่มีดัชนีคลัสเตอร์ที่ต้องบำรุงรักษาและการแตกแฟรกเมนต์เพิ่มเติมจะไม่เป็นปัญหาเนื่องจากการอ่านที่หายากมาก


1
คุณกำลังพูดถึง SQL Server หรือไม่?
a_horse_with_no_name

@a_horse_with_no_name ใช่ฉันลืมพูดถึง sry นั้น
marc.d

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


คำตอบ:


22

การใช้งานที่ถูกต้องเท่านั้นมีไว้สำหรับ

  • ตาราง staging ที่ใช้ในกระบวนการอิมพอร์ต / ส่งออก / ETL
  • ad-hoc สำรองชั่วคราวและระยะสั้นของตารางโดยใช้ SELECT * INTO..

โดยทั่วไปแล้วการจัดเตรียมตารางค่อนข้างแบนและถูกตัดทอนก่อน / หลังการใช้งาน

โปรดทราบว่าดัชนีกลุ่มมักจะมีขนาดเล็กเมื่อเทียบกับขนาดข้อมูล: ข้อมูลเป็นระดับต่ำสุดของโครงสร้างดัชนี

ตารางฮีปมีปัญหาเช่นกัน อย่างน้อยเหล่านี้:

ยังดู


2
โดยทั่วไปจะใช้ฮีปสำหรับสองสิ่งแยกกัน การจัดเตรียม ETL และตารางการทำงานที่ฉันใช้เพื่อเก็บข้อมูลชั่วคราวเมื่อตั้งค่าไว้ที่ขนาดใหญ่เพื่อให้ตาราง temp ทำงานได้อย่างมีประสิทธิภาพ ซึ่งทั้งหมดจะถูกตัดทอนเมื่อมีการโหลดครั้งถัดไป
Zane

คำถามที่ดีโดยวิธีการ
Zane

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

@BrentOzar: เห็นด้วยฉันทำมันตลอดเวลาด้วยตัวเอง จิตวิญญาณของคำตอบของฉันคือ "ตารางระยะยาวและถาวร" แต่ฉันจะอัปเดต
gbn

9

ข้อพิจารณาที่สำคัญ

ฉันเห็นข้อดีอย่างหนึ่งที่สำคัญสำหรับฮีปและอีกหนึ่งสำหรับตารางคลัสเตอร์รวมถึงข้อพิจารณาที่สามซึ่งสามารถไปได้ด้วยวิธีใดวิธีหนึ่ง

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

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

  • ดัชนีเกี่ยวกับ RID อ้างอิงถึงกองซึ่งเป็น 64 บิต ดังที่ได้กล่าวไว้แล้วดัชนีที่ไม่ได้ทำคลัสเตอร์บนตารางคลัสเตอร์อ้างอิงถึงคีย์การทำคลัสเตอร์ซึ่งอาจมีขนาดเล็กลง (32 บิตINT), เหมือนกัน (64 บิตBIGINT) หรือใหญ่กว่า (48 บิตDATETIME2()บวก 32 บิต)INT ) หรือ GUID แบบ 128 บิต) เห็นได้ชัดว่าการอ้างอิงที่กว้างขึ้นทำให้ดัชนีมีขนาดใหญ่ขึ้นและมีราคาแพงขึ้น

ข้อกำหนดด้านพื้นที่

ด้วยสองตารางเหล่านี้:

CREATE TABLE TmpClustered
(
ID1 INT NOT NULL,
ID2 INT NOT NULL
)
ALTER TABLE TmpClustered ADD CONSTRAINT PK_Tmp1 PRIMARY KEY CLUSTERED (ID1)
CREATE UNIQUE INDEX UQ_Tmp1 ON TmpClustered (ID2)

CREATE TABLE TmpNonClustered
(
ID1 INT NOT NULL,
ID2 INT NOT NULL
)
ALTER TABLE TmpNonClustered ADD CONSTRAINT PK_Tmp2 PRIMARY KEY NONCLUSTERED (ID1)
CREATE UNIQUE INDEX UQ_Tmp2 ON TmpNonClustered (ID2)

... แต่ละรายการมีบันทึก 8.7 M พื้นที่ที่ต้องการคือ 150 MB สำหรับข้อมูลสำหรับทั้งคู่ 120 MB สำหรับดัชนีของตารางคลัสเตอร์ 310 MB สำหรับดัชนีของตารางที่ไม่ทำคลัสเตอร์ สิ่งนี้สะท้อนให้เห็นว่าดัชนีคลัสเตอร์นั้นแคบกว่า RID และดัชนีคลัสเตอร์นั้นส่วนใหญ่เป็น "freebie" หากไม่มีดัชนีที่ไม่ซ้ำกันID2พื้นที่ดัชนีต้องการลดลงถึง 155 MB สำหรับตารางที่ไม่ใช่คลัสเตอร์ (ครึ่งตามที่คุณคาดหวัง) แต่เพียง 150 KBสำหรับ PK แบบคลัสเตอร์ - ใกล้เคียงกับอะไรเลย

ดังนั้นดัชนีที่ไม่คลัสเตอร์ของเขตข้อมูล 32 บิตในตารางคลัสเตอร์ที่มีดัชนี 32 บิต (64 บิตทั้งหมดในนาม) ใช้เวลา 120 MB ในขณะที่ดัชนีของเขตข้อมูล 32 บิตในกองที่มี 64 บิต RID (ทั้งหมด 96 บิตในนาม) ใช้เวลา 155 MB ซึ่งน้อยกว่าที่เพิ่มขึ้น 50% เล็กน้อยคาดว่าจะไร้เดียงสาตั้งแต่ 64- บิตถึง 96- บิต แต่แน่นอนว่ามันมีค่าใช้จ่ายซึ่งช่วยลดความแตกต่างของขนาดได้อย่างมีประสิทธิภาพ

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

การเพิ่มข้อมูลความยาวแปรผันแบบสุ่ม ~ 40 ไบต์ไม่ได้ทำให้การเปลี่ยนแปลงนี้มีความเท่าเทียมกัน การแทนที่INTs ด้วย UUID แบบกว้างก็ไม่ได้เป็นเช่นนั้น (แต่ละตารางช้าลงเป็นเท่ากัน) ระยะของคุณอาจแตกต่างกันไป แต่ในกรณีส่วนใหญ่ว่าดัชนีพร้อมใช้งานนั้นสำคัญกว่าประเภทใด

บิตและชิ้นส่วน

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

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

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

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

TL; DR

ฉันเป็นคนเก็บข้อมูลไม่ใช่ผู้เชี่ยวชาญ OLTP สำหรับตารางความจริงฉันมักจะใช้ดัชนีการจัดกลุ่มบนสนามซึ่งส่วนใหญ่มีแนวโน้มที่จะต้องใช้การสแกนช่วงซึ่งมักจะเป็นเขตข้อมูลวันที่ สำหรับตารางมิติที่ฉันทำคลัสเตอร์บน PK ดังนั้นจึงมีการกำหนดล่วงหน้าสำหรับการผสานเข้าร่วมกับตารางข้อเท็จจริง

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


5

ฉันคิดว่าการพูดว่า "การใช้งานที่ถูกต้องเพียงอย่างเดียวคือสำหรับตารางการ staging ที่ใช้ในกระบวนการนำเข้า / ส่งออก / ETL" เป็นข้อ จำกัด เล็กน้อยในการพูดอย่างน้อยที่สุด คุณต้องใช้กรณีการใช้งานที่คาดหวังของระบบและจากนั้นเลือกตามความได้เปรียบของฮีปหรือตารางที่จัดระเบียบดัชนี (ฉันรู้ว่าคำศัพท์ Oracle แต่มันอธิบายได้ดี)

คลังสินค้าของเราโหลดประมาณ 1.5 พันล้านแถวต่อวันและต้องสนับสนุนการเขียนและการประมวลผลที่เกิดขึ้นพร้อมกันสูงรวมถึงการอ่าน ที่เก็บเชิงสัมพันธ์สนับสนุนฐานข้อมูล OLAP และทำให้ผู้อ่านมีแนวโน้มที่จะสแกนตารางเป็นหลัก รายงานและฟีดดาวน์สตรีมที่สร้างขึ้นโดยทั่วไปยังไม่สามารถเลือกได้เพียงพอที่ดัชนีใด ๆ จะเป็นประโยชน์ ระบบสนับสนุนหน้าต่างเลื่อนของข้อมูลและเมื่อมีการโหลดตารางเราไม่ค่อยเขียนมันอีกและให้การใช้งานที่ค่อนข้างแย่ของการแบ่งพาร์ติชันตารางที่ต้องการล็อค Sch-M สำหรับการแบ่งพาร์ติชันสวิตช์และผสานกับล็อค Sch-S สำหรับอ่าน ฯลฯ ระบบต้องใช้ประโยชน์จากหลาย ๆ ตารางแม้ว่าเราจะมีตารางที่แบ่งพาร์ติชันด้วย การใช้ตารางจำนวนมากอำนวยความสะดวกในการแบ่งส่วนข้อมูลและรอบการล้างข้อมูลในขณะที่ยังลดความขัดแย้ง

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

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

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

[แก้ไข] ฉันควรจะชัดเจนว่าเฉพาะตารางความจริงที่ไม่ได้แบ่งพาร์ติชันของเราคือกอง ตารางที่แบ่งพาร์ติชันและตารางมิติทั้งหมดมีดัชนีแบบคลัสเตอร์เพื่อสนับสนุนการค้นหาที่มีประสิทธิภาพเป็นต้น [แก้ไข 2] แก้ไข 2.5 ถึง 1.5 พันล้านรายการ ตุ๊ยตัวเลขสองตัวนั้นติดกัน จะเกิดอะไรขึ้นเมื่อพิมพ์คำตอบบนโทรศัพท์ฉันเดาว่า ...

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