การออกแบบฐานข้อมูล SQL Server สำหรับข้อมูล“ เก็บถาวร แต่พร้อมใช้งาน”


12

เรามีฐานข้อมูลขนาดใหญ่นี้ (> 1TB) ที่เราตั้งใจจะ "ลดขนาด" ฐานข้อมูลหมุนรอบเอนทิตีหลักหนึ่งเรียกว่า "เยี่ยมชม" สำหรับการอภิปรายสมมติว่ามันเป็นฐานข้อมูลสำหรับการปฏิบัติทางการแพทย์

มี "ประเภท" การเข้าชม 30 ครั้งเช่นขั้นตอนรายปีการติดตามการฉีดวัคซีนและอื่น ๆ แต่ละรายการเป็นตารางเงินอุดหนุนสำหรับ "การเยี่ยมชม" เช่น "visit_immuno"

ฐานข้อมูลได้สะสมข้อมูล 12 ปีมาตั้งแต่ปี 2000 มีคนเสนอว่าเราเก็บข้อมูลประมาณ 3 ปีในรุ่น "สด" และให้เวลาที่เหลืออยู่ในฐานข้อมูล "old_data" วันที่จะถูกเก็บไว้เฉพาะในตาราง "เยี่ยมชม" เนื่องจากมันถูกทำให้เป็นมาตรฐาน ตารางเยี่ยมชมยังมีROWVERSIONคอลัมน์และคอลัมน์BIGINTหลอก (คลัสเตอร์) สำหรับ intents และวัตถุประสงค์สมมติว่ากุญแจสำคัญในการจัดกลุ่มเป็นประชากรโดยลำดับ (SQL Server 2012 องค์กร) - cidเราจะตั้งชื่อมันว่า

คำสั่งvisit.dateนี้ไม่ได้อยู่ในลำดับเดียวกับคีย์การจัดกลุ่มตัวอย่างเช่นเมื่อแพทย์ไปตรวจเยี่ยมเพิ่มเติมและกลับมาพร้อมกับข้อมูล "กระเป๋าเอกสาร" ของเขามันจะถูกรวมเข้าไว้ในตารางหลัก นอกจากนี้ยังมีการปรับปรุงบางอย่างเพื่อ "ไปที่" ตารางที่จะทำให้ROWVERSIONคอลัมน์ที่จะออกจากซิงค์กับทั้งสองcidและdateคอลัมน์ - จะนำมันก็ไม่ROWVERSIONหรือcidจะทำให้คีย์พาร์ทิชันที่เหมาะสมด้วยเหตุผลนี้

กฎธุรกิจสำหรับการลบข้อมูลจาก "ชีวิต" คือการที่visit.dateจะต้องมากกว่า 36 เดือนและเป็นเด็กที่visit_paymentบันทึกจะต้องมีอยู่ นอกจากนี้ "old_data" ฐานข้อมูลไม่ได้มีการใด ๆ visit%ของตารางฐานยกเว้น

ดังนั้นเราจึงจบลงด้วย:

Live DB (ใช้ชีวิตประจำวัน) - ตารางทั้งหมด Old-Data DB - ข้อมูลเก่าสำหรับvisit%ตาราง

ข้อเสนอเรียกร้องให้รวมฐานข้อมูลที่เป็นเปลือกที่มีคำพ้องกับตารางฐานทั้งหมดในLive DB(ยกเว้นvisit%) รวมทั้งมุมมองที่ยูเนี่ยนทั้งหมดข้ามvisit%ตารางในฐานข้อมูลทั้งสอง

สมมติว่ามีการสร้างดัชนีเดียวกันในOld-DataDB แบบสอบถามจะทำงานได้ดีในมุมมอง UNION-ALL หรือไม่ สิ่งที่ประเภทของรูปแบบแบบสอบถามอาจเดินทางถึงแผนการดำเนินการสำหรับยูเนี่ยน-ALL ชม ?


3
แรงจูงใจสำหรับ a) การเก็บถาวรข้อมูลเก่าและ b) ทำให้เข้าถึงได้อย่างไร บำรุงรักษาค่าใช้จ่าย? ปัญหาประสิทธิภาพการทำงาน? แอปพลิเคชันที่เข้าถึงข้อมูลที่เก็บถาวรต้องสามารถเข้าถึงได้อย่างราบรื่นหรือไม่? มีหรือไม่มีการดัดแปลงแอปพลิเคชันหรือไม่
Mark Storey-Smith

(a) การรักษา db หลักให้เล็ก มันถูกจำลองแบบถึง 3 envs อื่น ๆ - dev, pre-test, test นอกจากนี้ยังมีกระจกจำลองและการสำรองข้อมูลทุกอย่างได้รับการสนับสนุนจากการจัดเก็บข้อมูลราคาแพง (b) เนื่องจากระบบดาวน์สตรีมสามารถเข้าถึงข้อมูลทั้งหมดได้ในขณะนี้สิ่งนี้จะรักษาสถานะที่เป็นอยู่ (c) อินสแตนซ์ของแอปสามารถทำงานกับฐานข้อมูล "รวม" ที่มีมุมมองทั้งหมด แต่ฉันสงสัยว่าอาจไม่ทำงานเลย
孔夫子

เพื่อชี้แจงข้อมูลที่เก็บถาวรยังคงอ่านเขียนถูกต้องหรือไม่ หรือว่าเป็นแบบอ่านอย่างเดียว?
Jon Seigel

ข้อมูลเก่าจะเปลี่ยนเป็นหน้าแบบอ่านอย่างเดียวและเต็ม 100% อินสแตนซ์ของแอพที่เชื่อมต่อกับมุมมองที่รวมกันอาจทำให้เกิดข้อผิดพลาดหากมีคนพยายามทำอะไรโง่ ๆ บนข้อมูลเก่า - เราไม่สนใจ
孔夫子

ฉันคิดว่ากลุ่มไฟล์แบบอ่านอย่างเดียวสำหรับข้อมูลประวัติและการสำรองข้อมูล / เรียกคืนบางส่วนจะกล่าวถึงเรื่องนี้โดยไม่เพิ่มโคลนฐานข้อมูลเชลล์และคำพ้องความหมาย ฉันพูดว่าคิดว่าฉันไม่ได้เข้าไปยุ่งกับกลไกของมันมาระยะหนึ่งแล้วและต้องรีเฟรชความทรงจำของฉัน ไม่มีความคิดว่ามันจะเหมาะกับการทำสำเนา แต่ฉันถามว่าทำไมคุณทำซ้ำฐานข้อมูลสดกับสภาพแวดล้อมดาวน์สตรีม
Mark Storey-Smith

คำตอบ:


4

เพื่อความสะดวกสมมติว่ามีการเรียกฐานข้อมูลที่ใช้งานจริงLiveDbและฐานข้อมูลที่ได้รับการเรียกArchiveDb

  • เพิ่มมุมมอง UNION ALL ในการLiveDbชี้ไปที่ตารางในArchiveDbฐานข้อมูลผ่านคำพ้อง (ไม่จำเป็นต้องทำ db รวมกับคำพ้องความหมาย)
  • "การแบ่งพาร์ติชัน" เปิดvisit.dateและลดคอลัมน์นี้เป็นvisit_paymentsเกินไปหากยังไม่มีอยู่ (สิ่งนี้จะช่วยปรับปรุงประสิทธิภาพการรวมที่อยู่ร่วม)
  • เก็บถาวรสองตารางขนาดใหญ่เท่านั้นหากเป็นไปได้ (ลดโอกาสในการเพิ่มประสิทธิภาพการเพิ่มประสิทธิภาพ) คงมุมมอง UNION ALL และตารางอื่น ๆ ไว้LiveDbเพื่อให้การรวมทั้งหมดเข้ากับตารางที่เล็กกว่านั้นถูกเก็บไว้ในเครื่อง
  • เพิ่มข้อ จำกัด การตรวจสอบในตารางทั้งสองLiveDbและArchiveDb ที่อธิบายช่วงของที่visit.dateมีอยู่ในตาราง visit.dataซึ่งจะช่วยเพิ่มประสิทธิภาพการกำจัดตารางที่เก็บจากทั้งสองพยายามและการสแกนที่มีคอลัมน์ คุณจะต้องอัปเดตข้อ จำกัด นี้เป็นระยะ
  • ในมุมมอง UNION ALL เพิ่มเกณฑ์ WHERE visit.dataที่กรองบน นี่คือนอกเหนือจากคำใบ้ที่คุณระบุไว้ในข้อ จำกัด การตรวจสอบแล้ว นี่เป็นการเพิ่มโอกาสของตัวกรองที่ถูกผลักลง
  • หากคุณมี EE ให้แบ่งพาร์ติชันตารางในฐานข้อมูลเก็บถาวร (แต่ไม่ใช่ในฐานข้อมูลสด) หากคุณต้องการจินตนาการให้ใช้การสำรองข้อมูล / กู้คืนระดับไฟล์ของฐานข้อมูลเก็บถาวรเพื่อประหยัดเวลาการสำรองข้อมูล
  • ลองพิจารณาวางAchiveDbในโหมดการกู้คืน SIMPLE หากยังไม่ได้ดำเนินการ คุณไม่ต้องการสำรองข้อมูลบันทึกธุรกรรมArchiveDb
  • ใช้ INSERT ... With (TABLOCK) SELECT ... With (ROWLOCK) เพื่อบังคับให้มีการบันทึกที่ปลายทางน้อยที่สุดเมื่อย้ายข้อมูลระหว่าง LiveDbและArchiveDb

ทั้งหมดข้างต้นไม่ได้รับประกันว่าเครื่องมือเพิ่มประสิทธิภาพจะกำจัดตารางเก็บถาวรออกจากการค้นหาและสแกน แต่มันทำให้มีโอกาสมากขึ้น

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

  • หากคุณเข้าร่วมvisit%ตารางด้วยกันและไม่รวมvisit.dataอยู่ในเกณฑ์การเข้าร่วม (นี่คือเหตุผลที่คุณต้องการ denormalise) ด้วยเหตุนี้คุณอาจต้องการแก้ไขข้อสงสัยของคุณ
  • หากคุณได้รับการเข้าร่วมแฮชระหว่างvisit.dataและตารางอื่น (เช่นส่วนข้อมูลวันที่) คุณอาจไม่ได้รับการกำจัดตารางที่ถูกต้อง
  • หากคุณพยายามที่จะรวมข้อมูลผ่านตารางที่เก็บถาวร
  • หากคุณกรองสิ่งใด ๆ ก็ตามvisit.dataตัวอย่างเช่นการค้นหาโดยตรงกับคีย์ของมุมมอง

สำหรับสถานการณ์ล่าสุดคุณสามารถป้องกันตัวคุณเองจากผลกระทบที่เลวร้ายที่สุดโดยเพิ่มข้อ จำกัด การตรวจสอบอื่น ๆ ในcid- ถ้าเป็นไปได้ คุณพูดถึงว่าลำดับcid"ไม่สะอาด" เกี่ยวกับวันที่และความก้าวหน้าของแถวในตาราง อย่างไรก็ตามคุณสามารถบำรุงรักษาตารางที่มีข้อมูล: "ไม่มีหมายเลขcidข้างต้นตั้งแต่นี้visit.data" หรือคล้ายกัน? นี่อาจทำให้มีข้อ จำกัด เพิ่มเติม

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

โดยวิธีการถ้าคุณรู้ว่าแบบสอบถามที่ดี - คุณอาจไม่จำเป็นต้องมีดัชนีเดียวกันในฐานข้อมูลทั้งสอง (นี้ถือว่าคุณมั่นใจ 100% ว่าคุณจะได้รับการกำจัดของตารางที่ถูกต้อง) ArchiveDbคุณอาจจะพิจารณาการใช้ร้านค้าคอลัมน์


-1

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


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