เหตุใดการรวมจึงไม่ดีเมื่อพิจารณาถึงความสามารถในการปรับขนาด


94

เหตุใดการเข้าร่วมจึงไม่ดีหรือ 'ช้า' ฉันรู้ว่าฉันได้ยินสิ่งนี้อีกครั้ง เจอคำพูดนี้

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

แหล่งที่มา

ฉันคิดเสมอว่าพวกเขาเร็วโดยเฉพาะเมื่อมองหา PK ทำไมพวกเขาถึง 'ช้า'?

sql  join 

คำตอบ:


101

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

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

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

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

  • เข้าร่วมกับคีย์ตัวแทน (คอลัมน์อัตโนมัติ / ข้อมูลประจำตัว) แทนที่จะเป็นคีย์ธรรมชาติ ซึ่งหมายถึงการเปรียบเทียบที่เล็กกว่า (และเร็วกว่า) ในระหว่างการดำเนินการเข้าร่วม
  • ดัชนี
  • มุมมองที่เป็นรูปธรรม / จัดทำดัชนี (คิดว่านี่เป็นการรวมที่คำนวณล่วงหน้าหรือการลดมาตรฐานที่มีการจัดการ )
  • คอลัมน์จากการคำนวณ คุณสามารถใช้สิ่งนี้เพื่อแฮชหรือคำนวณคอลัมน์สำคัญของการเข้าร่วมล่วงหน้าได้เช่นนั้นสิ่งที่จะเป็นการเปรียบเทียบที่ซับซ้อนสำหรับการเข้าร่วมตอนนี้มีขนาดเล็กกว่ามากและอาจมีการจัดทำดัชนีไว้ล่วงหน้า
  • พาร์ติชันตาราง (ช่วยให้มีชุดข้อมูลขนาดใหญ่โดยการกระจายภาระไปยังดิสก์หลาย ๆ แผ่นหรือ จำกัด สิ่งที่อาจเป็นตารางสแกนลงไปที่การสแกนพาร์ติชัน)
  • OLAP (คำนวณผลลัพธ์ล่วงหน้าของการสืบค้น / การรวมบางประเภทซึ่งไม่เป็นความจริงมากนัก แต่คุณสามารถคิดว่านี่เป็นการทำให้เป็นมาตรฐานทั่วไป )
  • Replication, Availability Groups, Log shipping หรือกลไกอื่น ๆ เพื่อให้เซิร์ฟเวอร์หลายตัวตอบคำถามในการอ่านสำหรับฐานข้อมูลเดียวกันและปรับขนาดปริมาณงานของคุณในเซิร์ฟเวอร์หลาย ๆ
  • การใช้เลเยอร์การแคชเช่น Redis เพื่อหลีกเลี่ยงการเรียกใช้คิวรีซ้ำซึ่งต้องการการรวมที่ซับซ้อน

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

หากคุณเข้าร่วมช้าคุณอาจใช้ฐานข้อมูลไม่ถูกต้อง

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

* นั่นคือมีอยู่เป็นเอนทิตีที่แตกต่างจากคอลเลกชันของตารางเท่านั้น เหตุผลเพิ่มเติมสำหรับ rdbms จริงคือการเข้าถึงพร้อมกันอย่างปลอดภัย


14
ดัชนีควรจะอยู่ที่ด้านบนสุดของรายการ นักพัฒนาจำนวนมาก ( ไอ ) ดูเหมือนจะลืมพวกเขาเมื่อทำการทดสอบกับชุดข้อมูลขนาดเล็กจากนั้นนำฐานข้อมูลมาใช้ในการผลิต ฉันได้เห็นข้อความค้นหาที่เรียกใช้ลำดับที่เร็วกว่า 100,000 เท่าเพียงแค่เพิ่มดัชนี และนั่นคือดัชนีโดยพลการโดยไม่ต้องทำการวิเคราะห์ข้อมูลเชิงลึกใด ๆ เพื่อกำหนดส่วนผสมที่ดีที่สุดสำหรับการจับคู่คำนำหน้าซ้ายสุด
Duncan

ฉันคิดว่าฉันมีลำดับถูกต้อง - เป็นเพียงนักพัฒนาส่วนใหญ่ที่ทำรายการแรกแล้วดังนั้นดัชนีจึงเป็นรายการแรกที่พวกเขาจะต้องทำการเปลี่ยนแปลง
Joel Coehoorn

ในรายการที่สามของคุณคุณพูดถึง "มุมมองที่เป็นรูปธรรม / ดัชนี" คุณกำลังพูดถึงมุมมอง SQL ปกติหรืออย่างอื่น?
slolife

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

ขอบคุณ Joel ฉันจะต้องดูให้ดี
slolife

29

ร่วมสามารถช้ากว่าการหลีกเลี่ยงพวกเขาผ่าน de-ฟื้นฟู แต่ถ้าใช้อย่างถูกต้อง (เข้าร่วมในคอลัมน์ที่มีดัชนีความเหมาะสมอื่น ๆ ) พวกเขาจะไม่ช้าโดยเนื้อแท้

De-normalization เป็นหนึ่งในเทคนิคการเพิ่มประสิทธิภาพหลายอย่างที่คุณสามารถพิจารณาได้ว่าสคีมาฐานข้อมูลที่ออกแบบมาอย่างดีมีปัญหาด้านประสิทธิภาพหรือไม่


2
... ยกเว้นใน MySQL ซึ่งดูเหมือนจะมีปัญหาด้านประสิทธิภาพกับการรวมจำนวนมากไม่ว่าดัชนีของคุณจะมีลักษณะอย่างไร หรืออย่างน้อยก็มีในอดีต
Powerlord

2
ประเด็นที่นำมาหากมีปัญหาที่ทราบเกี่ยวกับ DBMS เฉพาะ (และอาจเป็นเวอร์ชัน) คำแนะนำนี้อาจสมเหตุสมผล แต่ตามคำแนะนำทั่วไปมันค่อนข้างทำให้เข้าใจผิดหากคุณใช้ฐานข้อมูลเชิงสัมพันธ์ ที่กล่าวว่ากลไกการจัดเก็บข้อมูลแบบไม่สัมพันธ์กันกำลังเป็นที่นิยมมากขึ้นของ Amazon's SimpleDB และ CouchDB ( couchdb.apache.org ) เป็นตัวอย่าง หากคุณได้รับการบริการที่ดีกว่าโดยทิ้งโมเดลเชิงสัมพันธ์ไว้ข้างหลังคุณควรทิ้งผลิตภัณฑ์ที่ปรับให้เหมาะสมที่สุดไว้เบื้องหลังด้วยและมองหาเครื่องมืออื่น ๆ
Tendayi Mawushe

13

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


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

12

ประการแรก raison d'etre (เหตุผลของการเป็น) ของฐานข้อมูลเชิงสัมพันธ์คือการสร้างแบบจำลองความสัมพันธ์ระหว่างเอนทิตี การเข้าร่วมเป็นเพียงกลไกที่เราสำรวจความสัมพันธ์เหล่านั้น แน่นอนว่าพวกเขามาในราคาเล็กน้อย แต่หากไม่มีการรวมก็ไม่มีเหตุผลที่จะมีฐานข้อมูลเชิงสัมพันธ์

ในโลกวิชาการเราได้เรียนรู้สิ่งต่างๆเช่นรูปแบบปกติต่างๆ (1, 2, 3, Boyce-Codd ฯลฯ ) และเราเรียนรู้เกี่ยวกับคีย์ประเภทต่างๆ (หลักต่างประเทศทางเลือกที่ไม่ซ้ำกัน ฯลฯ ) และวิธีการ สิ่งเหล่านี้เข้ากันได้ดีในการออกแบบฐานข้อมูล และเราเรียนรู้พื้นฐานของ SQL รวมถึงการจัดการทั้งโครงสร้างและข้อมูล (DDL & DML)

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

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

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

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

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

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

แล้วเราจะสมดุลตรงไหน? ไม่มีคำตอบเดียวที่ดีที่สุด คำตอบที่ดีกว่าทั้งหมดมักจะเป็นการประนีประนอมระหว่างความง่ายในการดูแลโครงสร้างการบำรุงรักษาข้อมูลและความง่ายในการสร้าง / บำรุงรักษาโค้ด โดยทั่วไปยิ่งข้อมูลซ้ำกันน้อยเท่าไหร่ก็ยิ่งดีเท่านั้น

แล้วทำไมบางครั้งการเข้าร่วมจึงช้า? บางครั้งการออกแบบเชิงสัมพันธ์ที่ไม่ดี บางครั้งการจัดทำดัชนีก็ไม่ได้ผล บางครั้งปัญหาเกี่ยวกับปริมาณข้อมูล บางครั้งก็เป็นข้อความค้นหาที่เขียนขึ้นอย่างน่ากลัว

ขออภัยสำหรับคำตอบที่ยืดยาวเช่นนี้ แต่ฉันรู้สึกว่าจำเป็นที่จะต้องให้บริบทที่เหมาะสมกับความคิดเห็นของฉันมากกว่าแค่การตอบสนองแบบ 4-bullet


10

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

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

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

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

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


8

การเข้าร่วมช้าหาก

  • ข้อมูลมีการจัดทำดัชนีไม่ถูกต้อง
  • ผลลัพธ์กรองไม่ดี
  • เข้าร่วมแบบสอบถามที่เขียนไม่ดี
  • ชุดข้อมูลมีขนาดใหญ่และซับซ้อนมาก

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

แหล่งที่มาของคุณให้ denormalization เป็นตัวเลือก สิ่งนี้ใช้ได้ตราบเท่าที่คุณใช้ทางเลือกอื่นที่ดีกว่าหมดแล้ว


7

การรวมอาจช้าหากจำเป็นต้องสแกนส่วนใหญ่ของบันทึกจากแต่ละด้าน

แบบนี้:

SELECT  SUM(transaction)
FROM    customers
JOIN    accounts
ON      account_customer = customer_id

แม้ว่าดัชนีจะถูกกำหนดไว้account_customerแต่ระเบียนทั้งหมดจากส่วนหลังก็ยังต้องได้รับการสแกน

สำหรับรายการคำค้นหานี้เครื่องมือเพิ่มประสิทธิภาพที่เหมาะสมอาจไม่ได้พิจารณาเส้นทางการเข้าถึงดัชนีด้วยซ้ำโดยทำHASH JOINหรือMERGE JOINแทน

โปรดทราบว่าสำหรับข้อความค้นหาเช่นนี้:

SELECT  SUM(transaction)
FROM    customers
JOIN    accounts
ON      account_customer = customer_id
WHERE   customer_last_name = 'Stellphlug'

การเข้าร่วมส่วนใหญ่อาจจะรวดเร็ว: อันดับแรกดัชนีcustomer_last_nameจะถูกใช้เพื่อกรอง Stellphlug ทั้งหมด (ซึ่งแน่นอนว่ามีจำนวนไม่มากนัก) จากนั้นจะมีการสแกนดัชนีaccount_customerสำหรับ Stellphlug แต่ละรายการเพื่อค้นหาธุรกรรมของเขา

แม้ว่าข้อเท็จจริงเหล่านี้อาจเป็นบันทึกหลายพันล้านรายการaccountsและcustomersมีเพียงไม่กี่รายการเท่านั้นที่จะต้องได้รับการสแกน


แต่ก็ยากที่จะหลีกเลี่ยง ออกแบบแอปของคุณเพื่อไม่ให้มีการดำเนินการค้นหาประเภทนี้บ่อยเกินไป
Andrey

1
หากมีการกำหนดดัชนีบนaccounts(account_customer)RDBMSes ส่วนใหญ่จะใช้ดัชนีนั้นเพื่อค้นหาว่าcustomersต้องสแกนแถวใดของฐานข้อมูล
jemfinch

ใช่ แต่มันก็ไม่ใช่การใช้งานที่ถูกอยู่ดี คุณสามารถจัดเก็บผลรวมในบางฟิลด์และอัปเดตในแต่ละธุรกรรม
Andrey

@jemfinch: ไม่พวกเขาจะไม่ สิ่งนี้จะต้องมีการสแกนดัชนีทั้งหมดเพียงเพื่อกรองลูกค้าออกจากนั้นสแกนดัชนีของลูกค้าในวงซ้อน A HASH JOINจะเร็วกว่ามากดังนั้นจึงเป็นสิ่งที่จะใช้ยกเว้นในฐานข้อมูลหลักทั้งหมดยกเว้นMySQLซึ่งจะทำให้เป็นcustomersผู้นำในลูปที่ซ้อนกัน (เนื่องจากมีขนาดเล็กกว่า)
Quassnoi

4

Joins are fast.การเข้าร่วมควรได้รับการพิจารณาการปฏิบัติมาตรฐานด้วยสคีมาฐานข้อมูลที่เป็นมาตรฐานอย่างเหมาะสม การเข้าร่วมช่วยให้คุณสามารถเข้าร่วมกลุ่มข้อมูลที่แตกต่างกันได้อย่างมีความหมาย อย่ากลัวการเข้าร่วม

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

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

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

นอกจากนี้ยังเป็นความจริงที่ว่านกบินได้เร็วขึ้นโดยไม่ต้องมีปีกใด ๆ แต่จะบินตรงลงไปเท่านั้น


3

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

ฐานข้อมูลส่วนใหญ่สามารถประมวลผลแบบสอบถามได้อย่างรวดเร็วโดยเลือก 5 ระเบียนจากตารางหลักและรวม 5 ระเบียนจากตารางที่เกี่ยวข้องสำหรับแต่ละระเบียน (สมมติว่ามีดัชนีที่ถูกต้อง) ตารางเหล่านี้สามารถมีหลายร้อยล้านรายการในแต่ละรายการหรือแม้แต่พันล้าน

เมื่อผลลัพธ์ของคุณเริ่มเติบโตขึ้นสิ่งต่างๆจะช้าลง โดยใช้ตัวอย่างเดียวกันหากตารางหลักให้ผลลัพธ์เป็นระเบียน 100K จะมีระเบียน "เข้าร่วม" 500K ที่ต้องค้นหา เพียงแค่ดึงข้อมูลจำนวนมากนั้นออกจากฐานข้อมูลพร้อมกับเพิ่มความล่าช้า

อย่าหลีกเลี่ยงการเข้าร่วมเพียงแค่รู้ว่าคุณอาจต้องเพิ่มประสิทธิภาพ / ทำให้เป็นมาตรฐานเมื่อชุดข้อมูลมีขนาด "ใหญ่มาก"


3

นอกจากนี้จากบทความที่คุณอ้างถึง:

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

และ

และถ้าคุณเป็นเว็บไซต์ขนาดใหญ่จริง ๆ คุณอาจไม่จำเป็นต้องกังวลเกี่ยวกับความซับซ้อนในระดับนี้

และ

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

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


2

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


ฉันไม่แน่ใจว่าเป็นความจริง ฉันรู้ว่า Teradata สามารถแจกจ่ายจอยระหว่างแอมป์ได้ เห็นได้ชัดว่าการรวมบางประเภทอาจยุ่งยาก / ยากกว่าแบบอื่น
Cade Roux

ดัชนีสามารถแบ่งพาร์ติชันใน RDBMS ได้ตั้งแต่ mysql ถึง oracle AFAIK ที่ปรับขนาด (กระจายและสามารถขนานกันได้)
Unreason

2

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

ทำไมการเข้าร่วมไม่ดีหรือ 'ช้า'

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


1

จำนวนข้อมูลชั่วคราวที่สร้างขึ้นอาจมากตามการรวม

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

ฉันได้รับมอบหมายให้ปรับขั้นตอนการจัดเก็บการค้นหาให้เหมาะสม

สิ่งแรกที่ฉันทำคือหากมีการค้นหาฟิลด์ใด ๆ ของตารางหลักฉันเลือกตารางชั่วคราวในฟิลด์เหล่านั้นเท่านั้น จากนั้นฉันเข้าร่วมตารางทั้งหมดด้วยตารางชั่วคราวนั้นก่อนที่จะทำการค้นหาที่เหลือ ค้นหาที่ซึ่งหนึ่งในช่องตารางหลักใช้เวลาน้อยกว่า 10 วินาที

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

การใช้งาน CPU ของเซิร์ฟเวอร์ SQL ก็ลดลงเช่นกัน


@BoltBait: เป็นข้อความที่คุณควรพยายามลดจำนวนแถวก่อนที่จะทำการเข้าร่วมหรือไม่?
unutbu

แน่นอนว่ามันได้ผลอย่างมหัศจรรย์ในกรณีของฉัน แต่ฉันจะไม่ปรับระบบให้เหมาะสมจนกว่าจะจำเป็น
BoltBait

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

1

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

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


1

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

ตัวอย่างที่อ้างถึงในบทความ - Flickr และ eBay - เป็นกรณีพิเศษ IMO ดังนั้นควรมี (และสมควรได้รับ) คำตอบที่ยอดเยี่ยม ผู้เขียนเรียกเฉพาะการขาด RI และขอบเขตของการทำซ้ำข้อมูลในบทความ

แอปพลิเคชันส่วนใหญ่ - อีกครั้ง IMO - ได้รับประโยชน์จากการตรวจสอบความถูกต้องและลดการทำซ้ำโดย RDBMS


0

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

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