ปรับปรุง:
บทความเหล่านี้ในบล็อกของฉันอธิบายความแตกต่างระหว่างวิธีการโดยละเอียดเพิ่มเติม:
มีสามวิธีในการค้นหาดังกล่าว:
LEFT JOIN / IS NULL
:
SELECT *
FROM common
LEFT JOIN
table1 t1
ON t1.common_id = common.common_id
WHERE t1.common_id IS NULL
NOT EXISTS
:
SELECT *
FROM common
WHERE NOT EXISTS
(
SELECT NULL
FROM table1 t1
WHERE t1.common_id = common.common_id
)
NOT IN
:
SELECT *
FROM common
WHERE common_id NOT IN
(
SELECT common_id
FROM table1 t1
)
เมื่อtable1.common_id
ใดที่ไม่สามารถเป็นโมฆะได้แบบสอบถามเหล่านี้ทั้งหมดจะเหมือนกันอย่างมีความหมาย
เมื่อเป็นโมฆะNOT IN
จะแตกต่างกันเนื่องจากIN
(และดังนั้นNOT IN
) จะส่งคืนNULL
เมื่อค่าไม่ตรงกับสิ่งใด ๆ ในรายการที่มี a NULL
.
สิ่งนี้อาจทำให้สับสน แต่อาจชัดเจนมากขึ้นหากเราจำไวยากรณ์ทางเลือกสำหรับสิ่งนี้:
common_id = ANY
(
SELECT common_id
FROM table1 t1
)
ผลลัพธ์ของเงื่อนไขนี้เป็นผลคูณบูลีนของการเปรียบเทียบทั้งหมดภายในรายการ แน่นอนว่าNULL
ค่าเดียวให้NULL
ผลลัพธ์ซึ่งแสดงผลลัพธ์ทั้งหมดNULL
ด้วย
เราไม่เคยไม่สามารถพูดได้แน่นอนว่าจะไม่เท่ากับอะไรจากรายการนี้อย่างน้อยตั้งแต่ค่าใดค่าหนึ่งคือcommon_id
NULL
สมมติว่าเรามีข้อมูลเหล่านี้:
common
--
1
3
table1
--
NULL
1
2
LEFT JOIN / IS NULL
และNOT EXISTS
จะกลับมา3
, NOT IN
จะกลับไม่มีอะไร (เพราะมันมักจะประเมินผลอย่างใดอย่างหนึ่งFALSE
หรือNULL
)
ในMySQL
ในกรณีที่คอลัมน์ไม่ใช่ nullable, LEFT JOIN / IS NULL
และNOT IN
มีนิด ๆ หน่อย ๆ (ร้อยละหลาย) NOT EXISTS
ที่มีประสิทธิภาพมากกว่า ถ้าคอลัมน์เป็นโมฆะNOT EXISTS
จะมีประสิทธิภาพมากที่สุด (อีกครั้งไม่มาก)
ในOracle
แบบสอบถามทั้งสามให้ผลแผนเดียวกัน (an ANTI JOIN
)
ในSQL Server
, NOT IN
/ NOT EXISTS
มีประสิทธิภาพมากขึ้นเนื่องจากLEFT JOIN / IS NULL
ไม่สามารถเพิ่มประสิทธิภาพให้กับANTI JOIN
โดยการเพิ่มประสิทธิภาพของมัน
ในPostgreSQL
, LEFT JOIN / IS NULL
และNOT EXISTS
มีประสิทธิภาพมากขึ้นกว่าNOT IN
ไซน์พวกเขาจะปรับไปยังAnti Join
ในขณะที่NOT IN
การใช้งานhashed subplan
(หรือแม้กระทั่งธรรมดาsubplan
ถ้าแบบสอบถามย่อยที่มีขนาดใหญ่เกินไปที่จะกัญชา)