เข้าร่วมเป็นคนขี้เกียจ?


169

เมื่อเร็ว ๆ นี้ฉันได้พูดคุยกับนักพัฒนารายอื่นที่อ้างกับฉันว่า JOIN (SQL) ไร้ประโยชน์ นี่เป็นความจริงทางเทคนิค แต่เขาเสริมว่าการใช้การเข้าร่วมนั้นมีประสิทธิภาพน้อยกว่าการร้องขอหลายครั้งและตารางลิงก์ในรหัส (C # หรือ Java)

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


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

91
ภาษาโปรแกรมสำหรับคนขี้เกียจ; มีประสิทธิภาพน้อยกว่าการเข้ารหัสคำสั่ง CPU ด้วยมือ :)
Michael McGowan

76
นักพัฒนาชื่ออะไร? ฉันต้องการให้แน่ใจว่าฉันไม่เคยจ้างเขา
Joe

39
@Michael meh โปรแกรมเมอร์จริง ๆ ใช้ butterflies ...
Marc Gravell

14
Re "นี่คือความจริง" ของคุณ - ไม่ใช่ไม่ใช่ ฐานข้อมูลทำงานผ่านทฤษฎีเซต ร่วมในชุดทำงานอย่างมากและเป็นประโยชน์ ...
Marc Gravell

คำตอบ:


188

ไม่เราควรหลีกเลี่ยงนักพัฒนาที่ถือความคิดเห็นที่ผิดอย่างไม่น่าเชื่อ

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

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

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


1
สิ่งที่เกี่ยวกับ 3-way ร่วม ไม่มีกรณีที่คุณควรทำในรหัส "ดีกว่า" หรือไม่
julien_c

56
เข้าร่วมในเซิร์ฟเวอร์แอปสามารถมีประสิทธิภาพมากขึ้นถ้าการเข้าร่วมกับฐานข้อมูลที่ทำให้เกิดความซ้ำซ้อนอย่างรุนแรงในชุดผลลัพธ์ส่งผ่านเครือข่าย พิจารณาตาราง A และ B ที่แต่ละแถวใน A เชื่อมโยงกับ 20 แถวใน B, B มีเพียง 100 แถวและเราต้องการดึง 1,000 แถวแรกจาก A กับแถวที่เกี่ยวข้องจาก B การเข้าร่วมในฐานข้อมูลจะส่งผลให้ 20 * 1,000 tuples ส่งผ่านเครือข่าย หากการเข้าร่วมเสร็จสิ้นในเซิร์ฟเวอร์แอป (ดึงข้อมูลตาราง B ทั้งหมดลงในหน่วยความจำก่อน) จะมีการส่งแถว 100 + 1,000 แถวทั่วทั้งเครือข่ายเท่านั้น
meriton

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

13
ฉันโชคดีมากที่ได้พูดคุยกับนักพัฒนาซอฟต์แวร์บางคนที่ทำงานบน SQL Server ที่ Microsoft มันจะทำให้คุณเวียนหัวได้ยินการเพิ่มประสิทธิภาพที่พวกเขาทำกับแบบสอบถาม ใครก็ตามที่คิดว่าพวกเขาฉลาดกว่าที่จะถูกตี
riwalk

2
@meriton ฉันประหลาดใจเล็กน้อย ฉันคาดว่าห้องสมุดลูกค้าจะเพิ่มประสิทธิภาพการรวมข้าม
Phil Lello

83

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

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

ในระยะสั้น: ฉันไม่เห็นด้วย ใน RDBMS ที่ร่วมเป็นพื้นฐาน หากคุณไม่ได้ใช้งานคุณจะไม่ได้ใช้เป็น RDBMS


46

เขาผิดในกรณีทั่วไป

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


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

1
@ LegendLength ฉันจะบอกว่ามันเป็นเรื่องจริงถ้ามันไม่ฉลาด ไม่จำเป็นต้องสมมติความฉลาดเพราะพวกเขาทำผิดแบบเดียวกับที่เราจำได้ว่าทำ (จริง ๆ แล้วสำหรับฉันนั่นอาจหมายถึงว่าพวกเขาไม่ฉลาด ... ) มันง่ายกว่า: มันไม่ค่อยช่วยให้ถูกไล่ออก มันก็โอเคที่จะผิดครั้งแล้วครั้งเล่า!
sehe

24

ไม่คุณไม่ควรทำ

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

นอกเหนือจากการเข้าร่วมแล้วอะไรคือจุดสำคัญในการใช้ฐานข้อมูล เขาอาจใช้ไฟล์ข้อความก็ได้เช่นกัน


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

19

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


ฉันเพิ่มความแม่นยำของคนขี้เกียจ: สำหรับคนขี้เกียจที่ไม่สนใจเรื่องการแสดงและชอบเขียนโค้ดให้น้อยลง ฉันคิดว่าการรวมสำหรับคนขี้เกียจ แต่ในกรณีนี้การรวมนั้นดีกว่าคำขอหลาย ๆ
Bastien Vandamme

3
@Dran Dane: การเข้าร่วมมีไว้สำหรับคนขี้เกียจใช่ ความจริงที่ว่าพวกเขามีแนวโน้มที่จะทำงานได้ดีก็คือมุมฉาก
Piskvor ออกจากอาคาร

16

อืมมมการเชื่อมโยงเป็นวิธีที่ฐานข้อมูลเชิงสัมพันธ์เชื่อมโยงตารางเข้าด้วยกัน ฉันไม่แน่ใจว่าเขากำลังทำอะไรอยู่

การโทรหลายครั้งไปยังฐานข้อมูลจะมีประสิทธิภาพมากกว่าการโทรครั้งเดียวได้อย่างไร? เครื่องยนต์ขนาดบวกของ sql ได้รับการปรับให้เหมาะกับการทำสิ่งนี้

บางทีเพื่อนร่วมงานของคุณอาจขี้เกียจเรียนรู้ SQL


12

ใช่คุณควรจะ.

และคุณควรใช้ C ++ แทน C # เนื่องจากประสิทธิภาพ C # สำหรับคนขี้เกียจ

ไม่ไม่ไม่. คุณควรใช้ C แทน C ++ เนื่องจากประสิทธิภาพ C ++ สำหรับคนขี้เกียจ

ไม่ไม่ไม่. คุณควรใช้แอสเซมบลีแทน C เนื่องจากประสิทธิภาพการทำงาน C สำหรับคนขี้เกียจ

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


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

11

"สิ่งนี้เป็นเรื่องจริงทางเทคนิค" - ในทำนองเดียวกันฐานข้อมูล SQL ไม่มีประโยชน์อะไรคือจุดประสงค์ในการใช้งานเมื่อคุณสามารถได้ผลลัพธ์เดียวกันโดยใช้ไฟล์ CSV หลาย ๆ ไฟล์และเชื่อมโยงกับรหัสเหล่านั้น Heck สิ่งที่เป็นนามธรรมสำหรับคนขี้เกียจลองกลับไปเขียนโปรแกรมในรหัสเครื่องบนฮาร์ดแวร์! ;)

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


2
+1 วลี "... จริงทางเทคนิค" จะทำงานได้ดีขึ้นถ้า OP คุ้นเคยกับการพูดunnecessaryมากกว่าuselessประโยคก่อนหน้า การบอกว่าการเข้าร่วมนั้นไร้ประโยชน์นั้นเป็นเรื่องจริงอย่างไม่มีเหตุผลโดยไม่จำเป็นต้องมีการพิจารณาทางเทคนิค ในกรณีใด ๆ ความเข้าใจผิดของ OP และของเพื่อนร่วมงานเกี่ยวกับจุดของ RDBMS นั้นไม่ใช่เรื่องแปลก: stackoverflow.com/q/5575682/47550
Paul Sasik

7

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

ใช่ฉันยอมรับว่าการรวมที่ทำที่ชั้นแอปพลิเคชันไม่มีประสิทธิภาพเทียบกับการรวมที่ดำเนินการโดยฐานข้อมูล เครือข่ายการสื่อสารเพิ่มเติมด้วย

โปรดทราบว่าฉันไม่ได้ยืนหยัดอย่างหนักในการหลีกเลี่ยงการรวม SQL


นั่นฟังดูเป็นข้อโต้แย้งที่สมเหตุสมผลกับ JOIN ในกรณีเฉพาะของคุณ ฉันจำได้ว่า FB Engineering โพสต์สิ่งที่คล้ายกันในบล็อกของพวกเขาการปรับขนาดก็สำคัญเช่นกัน อนิจจามีโปรแกรมเมอร์เพียงไม่กี่% ที่จะต้องทำสิ่งนี้ แต่หลายคนคิดว่าพวกเขาทำเพราะ OMG Facebook ทำเช่นนั้น ";)
Piskvor ออกจากอาคารเมื่อ

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

@Jodrell: ใช่พวกเขาเก่งในการเข้าร่วม อีกครั้งมีมุมกรณีที่คุณต้องการที่จะลดความสง่างามของการรวมเพื่อให้ได้พลังงานมากขึ้น ฉันได้พบหนึ่งในสถานการณ์ดังกล่าว เราได้ลองใช้วิธีแก้ปัญหาที่เป็นไปได้ทั้งหมดและแน่นอนว่าวิธีแก้ปัญหาแบบไม่เข้าร่วมนั้นเร็วที่สุดในสถานการณ์เฉพาะนั้น และไม่ไม่มีอะไรที่จะทำงานที่เซิร์ฟเวอร์นั้น ขั้นตอนการจัดเก็บจะไม่ทำให้คุณช้าลงหากคุณไม่มี;)
Piskvor ออกจากอาคารเมื่อ

5

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

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


5

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

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

ฉันปล่อยให้คุณตัดสินใจ


5

ลองพิจารณาตัวอย่าง: ตารางที่มีระเบียนใบแจ้งหนี้และตารางที่เกี่ยวข้องที่มีการบันทึกรายการโฆษณาใบแจ้งหนี้ พิจารณารหัสหลอกลูกค้า:

for each (invoice in invoices)
    let invoiceLines = FindLinesFor(invoice)
...

หากคุณมี 100,000 ใบแจ้งหนี้ที่มี 10 บรรทัดแต่ละรหัสนี้จะค้นหา 10 บรรทัดใบแจ้งหนี้จากตาราง 1 ล้านและจะทำเช่นนั้น 100,000 ครั้ง เมื่อขนาดของตารางเพิ่มขึ้นจำนวนการดำเนินการที่เลือกจะเพิ่มขึ้นและค่าใช้จ่ายของการดำเนินการเลือกแต่ละครั้งจะเพิ่มขึ้น

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

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

ลองนึกภาพทำสิ่งนี้ด้วยตัวเอง คุณมีรายการนักเรียนและสมุดบันทึกเรียงตามตัวอักษรที่มีรายงานผลการเรียนของนักเรียนทั้งหมด (หนึ่งหน้าต่อชั้นเรียน) สมุดบันทึกเรียงตามชื่อของนักเรียนเรียงตามลำดับเดียวกับรายการ คุณต้องการดำเนินการอย่างไร

  1. อ่านชื่อจากรายการ
  2. เปิดสมุดบันทึก
  3. ค้นหาชื่อนักเรียน
  4. อ่านผลการเรียนของนักเรียนเปลี่ยนหน้าจนกว่าคุณจะถึงนักเรียนคนต่อไปหรือหน้าสุดท้าย
  5. ปิดสมุดบันทึก
  6. ทำซ้ำ

หรือ:

  1. เปิดสมุดบันทึกไปที่หน้าแรก
  2. อ่านชื่อจากรายการ
  3. อ่านคะแนนใด ๆ สำหรับชื่อนั้นจากสมุดบันทึก
  4. ทำซ้ำขั้นตอนที่ 2-3 จนกระทั่งถึงจุดสิ้นสุด
  5. ปิดสมุดบันทึก

5

ดูเหมือนกรณีคลาสสิกของ " ฉันสามารถเขียนได้ดีกว่า " กล่าวอีกนัยหนึ่งเขาเห็นบางสิ่งที่เขาเห็นว่าเป็นอาการปวดคอ (เขียนเป็นจำนวนมากใน SQL) และพูดว่า "ฉันแน่ใจว่าฉันสามารถเขียนได้ดีกว่าและได้ประสิทธิภาพที่ดีกว่า" คุณควรถามเขาว่า a) ฉลาดกว่าและ b) มีการศึกษามากกว่าคนทั่วไปที่อยู่ลึกเข้าไปใน Oracle หรือ SQL Server optimization code โอกาสที่เขาจะไม่เป็น


3

เขาผิดอย่างแน่นอนที่สุด แม้ว่าจะมีข้อดีที่ชัดเจนในการจัดการข้อมูลภายในภาษาเช่น C # หรือ Java แต่การเชื่อมต่อนั้นเร็วที่สุดในฐานข้อมูลเนื่องจากลักษณะของ SQL เอง

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

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


3

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


3

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


3
เอ็นจิ้นฐานข้อมูลส่วนใหญ่จะทำสิ่งนี้เพื่อคุณเบื้องหลัง และเช่นใน MySQL คุณสามารถสร้างตารางในหน่วยความจำได้อย่างหมดจด (เอ็นMEMORYจิ้น) การใช้งานฟังก์ชั่นฐานข้อมูลโดยไม่ต้องใช้ฐานข้อมูลมักจะเป็นสัญญาณของกรณีร้ายแรงของ NIH;)
Piskvor ออกจากอาคาร

@phoog: ไม่ได้คิดค้นที่นี่ - ในคำอื่น ๆ "ฉันไม่ได้คิดอย่างนั้นดังนั้นจึงไม่มีอยู่" ล้อสี่เหลี่ยมจำนวนมากถูกประดิษฐ์ขึ้นใหม่ด้วยเหตุนี้ (และใช่บางครั้งการประดิษฐ์วงล้อใหม่นั้นมีประโยชน์เช่นถ้าคุณกำลังทำรถแข่งการประดิษฐ์ "เพียงเพราะ" ไม่น่าจะทำให้คุณได้ล้อที่ดีกว่า)
Piskvor ออกจากอาคาร

กล่าวอีกนัยหนึ่ง "ฉันไม่ได้ทำมันจึงต้องเป็นขยะ" นี่เป็นเพียงความจริงเท่านั้นที่ว่า "ฉันยังไม่ได้ทดสอบดังนั้นจึงอาจไม่เหมาะกับวัตถุประสงค์ของฉัน" ดังนั้นลองทดสอบก่อนที่คุณจะตัดสิน
Peter Lawrey

@Piskvor: ไม่จำเป็นต้องใช้ฐานข้อมูลสามารถใช้หน่วยความจำของระบบที่ทำงานอยู่ในขณะที่แอปพลิเคชันสามารถใช้หน่วยความจำของเซิร์ฟเวอร์แอปพลิเคชัน ใส่ที่แตกต่างกัน: ถ้าฐานข้อมูลอยู่บนโฮสต์เฉพาะการเข้าถึงแคชนั้นยังคงต้องใช้เครือข่ายแบนด์วิดท์และขึ้นอยู่กับเวลาแฝงของเครือข่าย แต่แคชใด ๆ ที่แอปพลิเคชันที่เก็บไว้สามารถสอบถามได้ด้วยความเร็ว
meriton

2

ไม่เพียง แต่จะได้รับการปรับปรุงให้ดีขึ้นในโค้ดฐานข้อมูลที่ ad-hoc C # / Java; แต่มักจะใช้เทคนิคการกรองหลายแบบซึ่งจะให้ประสิทธิภาพที่ดียิ่งขึ้น


2

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

select t1.field1 
from table1 t1
join table2 t2 
    on t1.id = t2.id
where t1.field2 = 'test'

สมมติว่าคุณมี 10 ล้านบันทึกในตารางที่ 1 และ 1 ล้านบันทึกในตารางที่ 2 สมมติว่ามี 9 ล้านระเบียนในตารางที่ 1 ตรงตามส่วนคำสั่ง สมมติว่ามีเพียง 15 คนเท่านั้นที่อยู่ใน table2 เช่นกัน คุณสามารถเรียกใช้คำสั่ง sql นี้ซึ่งหากได้รับการจัดทำดัชนีอย่างถูกต้องจะใช้เวลามิลลิวินาทีและส่งกลับ 15 รายการในเครือข่ายที่มีเพียง 1 คอลัมน์ของข้อมูล หรือคุณสามารถส่งสิบล้านเรคคอร์ดพร้อมคอลัมน์ข้อมูล 2 คอลัมน์และส่งอีก 1 ล้านเรคคอร์ดพร้อมคอลัมน์ข้อมูลหนึ่งคอลัมน์ในเครือข่ายและรวมเข้าด้วยกันบนเว็บเซิร์ฟเวอร์

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


2

ฉันได้ยินเรื่องนี้บ่อยครั้งในอาชีพของฉันในฐานะนักพัฒนาซอฟต์แวร์ เกือบทุกครั้งที่มีการระบุไว้คนที่อ้างว่าไม่มีความรู้เกี่ยวกับระบบฐานข้อมูลเชิงสัมพันธ์วิธีการทำงานและวิธีการใช้ระบบดังกล่าว

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

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

ดังนั้นคำตอบคือแน่นอน: ไม่JOINSไม่ไร้ประโยชน์เลย!


0

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


0

นอกจากว่าฉันเข้าใจผิดอย่างจริงจังตรรกะในคำถามนั้นมีข้อบกพร่องมาก

หากมี 20 แถวใน B สำหรับแต่ละ A, 1,000 แถวใน A หมายถึง 20k แถวใน B ไม่สามารถมีเพียง 100 แถวใน B เว้นแต่จะมีตารางจำนวนมาก "AB" ที่มี 20k แถวที่มีการแมป .

ดังนั้นเพื่อให้ได้ข้อมูลทั้งหมดเกี่ยวกับ 20 จาก 100 B แถวแมปไปยังแต่ละแถวคุณตาราง AB เกินไป ดังนั้นนี่อาจเป็น:

  • ชุดผลลัพธ์ 3 แถวคือ 100, 1,000 และ 20k และลูกค้าเข้าร่วม
  • ผลลัพธ์ A-AB-B ที่รวมเข้ากับชุด 20k แถว

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

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

คุณต้องเข้าร่วมที่ไหนสักแห่งและนั่นคือสิ่งที่ RDBMS ทำได้ดี ฉันไม่ต้องการทำงานกับรหัสลูกค้าลิงที่คิดว่าพวกเขาสามารถทำได้ดีกว่า

ภายหลัง:

หากต้องการเข้าร่วมในไคลเอนต์ต้องมีวัตถุถาวรเช่น DataTables (ใน. net) หากคุณมีชุดผลลัพธ์หนึ่งชุดมันสามารถถูกใช้ผ่านสิ่งที่เบากว่าเช่น DataReader ปริมาณสูง = ทรัพยากรไคลเอ็นต์จำนวนมากที่ใช้เพื่อหลีกเลี่ยงฐานข้อมูลที่เข้าร่วม

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