การใช้คำสั่ง build ใน JOIN สามารถแนะนำอุปสรรคการเพิ่มประสิทธิภาพได้ในบางกรณี?


35

ฉันได้รับความสนใจว่าการUSINGสร้าง (แทนON) ในส่วนFROMคำSELECTสั่งอาจทำให้เกิดปัญหาและอุปสรรคในการเพิ่มประสิทธิภาพในบางกรณี

ฉันหมายถึงคำสำคัญนี้:

เลือก *
จาก
เข้าร่วมขโดยใช้ (a_id)

ในกรณีที่ซับซ้อนมากขึ้น

บริบท: ความคิดเห็นสำหรับคำถามนี้

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

คำตอบที่สมบูรณ์แบบจะเป็นกรณีทดสอบเพื่อแสดงUSING (a_id)ด้วยประสิทธิภาพที่ต่ำกว่าเมื่อเปรียบเทียบกับข้อเข้าร่วมทางเลือกON a.a_id = b.a_id- ถ้านั่นสามารถเกิดขึ้นได้จริง


2
@ kgrittn: นั่นคือสิ่งที่ฉันคาดไว้จนถึงตอนนี้: USINGมันเร็วกว่าเล็กน้อย- เพราะมันทำให้คอลัมน์น้อยลงในเมทริกซ์ผลลัพธ์ การค้นพบของคุณย้อนกลับไปในปี 2005 และ 2008 ฉันคิดว่าปัญหาใด ๆ ได้รับการแก้ไขแล้วในขณะนี้ อย่างไรก็ตามฉันสามารถเห็นข้อ จำกัด ที่เป็นไปได้: JOIN ที่มีUSINGอาจจะต้องมีการใช้งานตามลำดับเนื่องจากคอลัมน์การเข้าร่วมที่เป็นผลลัพธ์เป็นผลิตภัณฑ์ร่วม ดังนั้นจึงอาจ จำกัด ตัวเลือกในการจัดลำดับใหม่ของ JOIN
Erwin Brandstetter

1
ฉันพบกระทู้นี้ซึ่งอาจมีบางสิ่งเกี่ยวกับการทำให้ฉันเลิกใช้บ่อยเท่าที่ฉันเคยมีเพราะการดูด้วยเงื่อนไขการใช้งานในการเข้าร่วมอาจทำให้เกิดปัญหากับการถ่ายโอนข้อมูล / คืนค่า: archives.postgresql.org/pgsql- ข้อบกพร่อง / 2011-06 / msg00030.php ฉันยังคงมีความรู้สึกที่จู้จี้มีหัวข้ออื่นที่เกี่ยวข้องกับปัญหาประสิทธิภาพการใช้ USING ที่การแก้ปัญหาคือการใช้ ON แต่ฉันจะให้ขึ้นในการค้นหาฉันคิดว่า อาจปลอดภัยที่จะใช้นอกมุมมองและอย่าลืมลองใช้แทนเป็นขั้นตอนการวินิจฉัยหากการสืบค้นช้า
kgrittn

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

2
@HLGEM: มันเป็นเพียงชื่อสัญลักษณ์และมีเพียงสองตารางเช่นในตัวอย่างของฉันไม่มีที่ว่างสำหรับความสับสน ถึงกระนั้นฉันก็แก้ไขคำถาม ไม่ต้องการสนับสนุนการใช้idชื่อคอลัมน์อย่างโชคร้าย
Erwin Brandstetter

2
@ChristiaanWesterbeek: ฉันไม่เห็นด้วย "ไปที่" สำหรับคำตอบในเชิงลึก Postgres คือ (ยัง) การส่งจดหมาย มีผู้ใช้ Postgres เพียงไม่กี่รายเท่านั้นที่ใช้งาน SO ดังนั้น แต่ผู้ที่ชื่นชอบ Postgres และผู้เชี่ยวชาญทั้งหมดอ่านรายชื่อผู้รับจดหมาย
a_horse_with_no_name

คำตอบ:


12

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

LEFT JOIN ( 
     a 
     JOIN b ON a.id = b.a_id
     JOIN c ON b.c_id = c.id
) ON a.id = something.a_id
LEFT JOIN (
     table1 t1
     JOIN table2 t2 ON t1.some_field = t2.other_field
     JOIN talbe3 t3 ON t2.yafield = t3.something_else
) ON ....
repeat a few more times

ในกรณีของเขาสิ่งที่เลวร้ายที่สุดของบล็อกการรวมเหล่านี้ทำให้เกิดการวนซ้ำซ้อนกันของแถว 200k แถวประมาณ 20k ครั้ง (คำนวณทางคณิตศาสตร์) และเนื่องจากคีย์ไม่สามารถถูกผลักไปยังดัชนีได้มันเป็นการสแกนตามลำดับ ซึ่งหมายความว่าแบบสอบถามโดยรวมใช้เวลาประมาณ 3 ชั่วโมงในการทำงานเนื่องจากการเปลี่ยนแปลงแผนแบบเรียงซ้อน ด้วยการกระจายการเข้าร่วมด้านซ้ายคีย์อาจถูกกดลงและการค้นหาทำงานในเวลาไม่กี่วินาที แน่นอนว่านี่ไม่ใช่สิ่งที่เท่าเทียมกันซึ่งเป็นสาเหตุที่นักวางแผนไม่สามารถปฏิบัติต่อพวกเขาได้อย่างเท่าเทียมกันดังนั้นจึงมีการคิดออกว่าแผนการนั้นคือการเข้าร่วมแฮชแล้วทำการวนซ้ำซ้อนกันซึ่งช้าลงอย่างเจ็บปวด

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

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