ไม่ได้อยู่กับไม่อยู่


538

แบบสอบถามใดเร็วกว่ากัน

ไม่มีอยู่:

SELECT ProductID, ProductName 
FROM Northwind..Products p
WHERE NOT EXISTS (
    SELECT 1 
    FROM Northwind..[Order Details] od 
    WHERE p.ProductId = od.ProductId)

หรือไม่ได้อยู่ใน:

SELECT ProductID, ProductName 
FROM Northwind..Products p
WHERE p.ProductID NOT IN (
    SELECT ProductID 
    FROM Northwind..[Order Details])

แผนการดำเนินการแบบสอบถามบอกว่าพวกเขาทั้งสองทำสิ่งเดียวกัน หากเป็นเช่นนั้นแบบฟอร์มที่แนะนำคืออะไร

สิ่งนี้ขึ้นอยู่กับฐานข้อมูล NorthWind

[แก้ไข]

เพิ่งพบบทความที่มีประโยชน์นี้: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx

ฉันคิดว่าฉันจะติดกับไม่มีอยู่


3
คุณลองใช้แผนด้วยการใช้การเข้าร่วมด้านซ้ายซึ่งเป็นโมฆะหรือไม่?
— Sebas

1
ไม่ได้อยู่ในและไม่มีอยู่ไม่เหมือนกัน ลองดูที่ลิงค์นี้เพื่อดูความแตกต่างระหว่างพวกเขา: weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx
— Ameya Gokhale

2
ฉันสงสัยว่าฐานข้อมูลแตกต่างกันหรือไม่ แต่ในเกณฑ์มาตรฐานล่าสุดของฉันกับ PostgreSQL NOT INแบบสอบถามนี้: SELECT "A".* FROM "A" WHERE "A"."id" NOT IN (SELECT "B"."Aid" FROM "B" WHERE "B"."Uid" = 2)เกือบ 30 เท่าเร็วเท่านี้NOT EXISTS:SELECT "A".* FROM "A" WHERE (NOT (EXISTS (SELECT 1 FROM "B" WHERE "B"."user_id" = 2 AND "B"."Aid" = "A"."id")))
— PhươngNguyễn


1
@rcdmk คุณตรวจสอบวันที่ตามคำถามหรือไม่
— ilitirit

คำตอบ:


693

NOT EXISTSฉันมักจะเริ่มต้นกับ

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

เมื่อไม่อนุญาตProducts.ProductIDหรือไม่[Order Details].ProductIDอนุญาตให้NULLดำเนินการNOT INดังกล่าวกับแบบสอบถามต่อไปนี้

SELECT ProductID,
       ProductName
FROM   Products p
WHERE  NOT EXISTS (SELECT *
                   FROM   [Order Details] od
                   WHERE  p.ProductId = od.ProductId) 

แผนการที่แน่นอนอาจแตกต่างกันไป แต่สำหรับข้อมูลตัวอย่างของฉันฉันได้รับดังต่อไปนี้

ทั้ง NULL

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

/*Not valid syntax but better reflects the plan*/ 
SELECT p.ProductID,
       p.ProductName
FROM   Products p
       LEFT ANTI SEMI JOIN [Order Details] od
         ON p.ProductId = od.ProductId 

ถ้าไม่[Order Details].ProductIDสามารถNULLสืบค้นได้

SELECT ProductID,
       ProductName
FROM   Products p
WHERE  NOT EXISTS (SELECT *
                   FROM   [Order Details] od
                   WHERE  p.ProductId = od.ProductId)
       AND NOT EXISTS (SELECT *
                       FROM   [Order Details]
                       WHERE  ProductId IS NULL) 

เหตุผลสำหรับสิ่งนี้คือความหมายที่ถูกต้องหาก[Order Details]มีNULL ProductIds ใด ๆคือไม่ส่งคืนผลลัพธ์ ดูการต่อต้านการรวมกึ่งและการเก็บพักการนับแถวเพื่อตรวจสอบสิ่งนี้ที่เพิ่มลงในแผน

หนึ่ง NULL

หากProducts.ProductIDมีการเปลี่ยนแปลงเพื่อให้สามารถNULLใช้งานได้แบบสอบถามก็จะกลายเป็น

SELECT ProductID,
       ProductName
FROM   Products p
WHERE  NOT EXISTS (SELECT *
                   FROM   [Order Details] od
                   WHERE  p.ProductId = od.ProductId)
       AND NOT EXISTS (SELECT *
                       FROM   [Order Details]
                       WHERE  ProductId IS NULL)
       AND NOT EXISTS (SELECT *
                       FROM   (SELECT TOP 1 *
                               FROM   [Order Details]) S
                       WHERE  p.ProductID IS NULL) 

สาเหตุที่เป็นเพราะNULL Products.ProductIdไม่ควรส่งคืนในผลลัพธ์ยกเว้นว่าNOT INแบบสอบถามย่อยจะไม่ส่งคืนผลลัพธ์เลย (เช่น[Order Details]ตารางว่างเปล่า) ในกรณีที่ควร ในแผนสำหรับข้อมูลตัวอย่างของฉันสิ่งนี้ถูกนำไปใช้โดยการเพิ่มการต่อต้านกึ่งเข้าร่วมดังต่อไปนี้

ทั้ง NULL

ผลของสิ่งนี้จะปรากฏในบล็อกโพสต์ที่ลิงก์โดย Buckleyแล้ว ในตัวอย่างมีจำนวนของการอ่านเชิงตรรกะเพิ่มขึ้นจากประมาณ 400 ถึง 500,000

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

นี่ไม่ใช่แผนการดำเนินการที่เป็นไปได้สำหรับคอลัมน์NOT INa NULL-able เท่านั้น บทความนี้แสดงอีกอันหนึ่งสำหรับการสืบค้นAdventureWorks2008ฐานข้อมูล

สำหรับคอลัมน์NOT INบนNOT NULLหรือNOT EXISTSเทียบกับคอลัมน์nullable หรือ non nullable จะให้แผนดังต่อไปนี้

ไม่มีอยู่จริง

เมื่อคอลัมน์เปลี่ยนเป็นNULLเปิดใช้งานNOT INแผนจะมีลักษณะเหมือนในขณะนี้

Not In - Null

มันเพิ่มผู้ประกอบการเข้าร่วมภายในพิเศษให้กับแผน เครื่องมือนี้อธิบายไว้ที่นี่อธิบายที่นี่มันคือทั้งหมดที่มีการแปลงดัชนีเดียวที่มีความสัมพันธ์ก่อนหน้านี้พยายามที่Sales.SalesOrderDetail.ProductID = <correlated_product_id>จะหาสองหาต่อแถวด้านนอก อีกหนึ่งเปิดอยู่WHERE Sales.SalesOrderDetail.ProductID IS NULLหนึ่งเพิ่มเติมได้ที่

เนื่องจากสิ่งนี้อยู่ภายใต้การรวมกึ่งต่อต้านถ้าหากส่งคืนแถวใด ๆ การค้นหาที่สองจะไม่เกิดขึ้น อย่างไรก็ตามหากSales.SalesOrderDetailไม่มีสิ่งใด ๆNULL ProductIDมันจะเพิ่มจำนวนการค้นหาที่ต้องการ


4
ฉันขอถามได้อย่างไรว่าคุณจะได้กราฟแสดงโปรไฟล์แบบนี้ได้อย่างไร
— xis

5
@xis นี่คือแผนการดำเนินการที่เปิดใน SQL Sentry plan explorer นอกจากนี้คุณยังสามารถดูแผนการดำเนินการกราฟิกใน SSMS
— Martin Smith

ฉันขอบคุณสิ่งนี้ด้วยเหตุผลเดียวที่: NOT EXISTSทำหน้าที่ตามที่ฉันคาดหวังNOT INในการทำงาน (ซึ่งไม่เป็นเช่นนั้น)
— levininja

ด้วย NOT EXISTS ฉันพยายามใช้ SELECT 1 เช่น NOT EXISTS (SELECT 1 จากบางสิ่งที่บางครั้ง) เพื่อให้ฐานข้อมูลไม่จำเป็นต้องส่งคืนคอลัมน์จากดิสก์ การใช้อธิบายเพื่อตรวจสอบว่าสิ่งนี้สร้างความแตกต่างในกรณีของคุณอาจเป็นความคิดที่ดี
— Mayur Patel

4
@Mayur ไม่จำเป็นต้องทำสิ่งนี้ใน SQL Server stackoverflow.com/questions/1597442/…
— Martin Smith

84

นอกจากนี้โปรดทราบว่า NOT IN ไม่เทียบเท่ากับ NOT EXISTS เมื่อเป็นโมฆะ

โพสต์นี้อธิบายได้ดีมาก

http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/

เมื่อเคียวรีย่อยส่งคืนค่า null หนึ่งค่า NOT IN จะไม่ตรงกับแถวใด ๆ

สาเหตุของเรื่องนี้สามารถพบได้โดยดูที่รายละเอียดว่าการดำเนินงาน NOT IN หมายถึงอะไร

สมมติว่าเพื่อวัตถุประสงค์ในการภาพประกอบมีแถว 4 แถวในตารางชื่อ t มีคอลัมน์ชื่อ ID พร้อมค่า 1..4

WHERE SomeValue NOT IN (SELECT AVal FROM t)

เทียบเท่ากับ

WHERE SomeValue != (SELECT AVal FROM t WHERE ID=1)
AND SomeValue != (SELECT AVal FROM t WHERE ID=2)
AND SomeValue != (SELECT AVal FROM t WHERE ID=3)
AND SomeValue != (SELECT AVal FROM t WHERE ID=4)

สมมุติว่า AVal ต่อไปคือ NULL โดยที่ ID = 4 ดังนั้น! = การเปรียบเทียบจะส่งคืน UNKNOWN ตารางความจริงเชิงตรรกะสำหรับ AND ระบุว่า UNKNOWN และ TRUE คือ UNKNOWN, UNKNOWN และ FALSE เป็น FALSE ไม่มีค่าที่สามารถเป็น AND'd กับ UNKNOWN เพื่อสร้างผลลัพธ์ TRUE

ดังนั้นถ้าแถวใด ๆ ของเคียวรีย่อยส่งคืน NULL ตัวดำเนินการ NOT IN ทั้งหมดจะประเมินเป็น FALSE หรือ NULL และจะไม่มีการส่งคืนเร็กคอร์ดใด


24

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


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

15

จริงๆแล้วฉันเชื่อว่านี่จะเป็นวิธีที่เร็วที่สุด:

SELECT ProductID, ProductName 
    FROM Northwind..Products p  
          outer join Northwind..[Order Details] od on p.ProductId = od.ProductId)
WHERE od.ProductId is null

2
อาจไม่ใช่วิธีที่เร็วที่สุดเมื่อเครื่องมือเพิ่มประสิทธิภาพกำลังทำงาน แต่จะเร็วขึ้นเมื่อไม่ได้ใช้งาน
— เคด Roux

2
เขาอาจทำให้ข้อความค้นหาของเขาง่ายขึ้นสำหรับโพสต์นี้ด้วย
— Kip

1
เห็นด้วยด้านนอกซ้ายเข้าร่วมมักจะเร็วกว่าแบบสอบถามย่อย
— HLGEM

7
@HLGEM ไม่เห็นด้วย จากประสบการณ์ของผมกรณีที่ดีที่สุดสำหรับ LOJ ก็คือพวกมันเหมือนกันและ SQL Server จะแปลง LOJ เป็นการรวมกึ่งต่อต้าน ในกรณีที่เลวร้ายที่สุด SQL Server LEFT เข้าร่วมทุกอย่างและกรองค่า NULLs ออกหลังจากนั้นซึ่งอาจไม่มีประสิทธิภาพมากขึ้น ตัวอย่างของที่อยู่ด้านล่างของบทความนี้
— Martin Smith

12

ฉันมีตารางที่มีระเบียนประมาณ 120,000 รายการและจำเป็นต้องเลือกเฉพาะรายการที่ไม่มีอยู่ (จับคู่กับคอลัมน์ varchar) ในอีกสี่ตารางที่มีจำนวนแถวประมาณ 1500, 4000, 40000, 200 ตารางที่เกี่ยวข้องทั้งหมดมีดัชนีที่ไม่ซ้ำกัน ที่เกี่ยวข้อง Varcharคอลัมน์ที่

NOT IN ใช้เวลาประมาณ 10 นาที NOT EXISTSใช้เวลา 4 วินาที

ฉันมีแบบสอบถามแบบเรียกซ้ำซึ่งอาจมีส่วนที่ไม่ได้รับการแก้ไขซึ่งอาจใช้เวลา 10 นาที แต่ตัวเลือกอื่นที่ใช้เวลา 4 วินาทีอธิบายอย่างน้อยสำหรับฉันที่NOT EXISTSดีกว่าหรืออย่างน้อยINและEXISTSไม่เหมือนกันและคุ้มค่าเสมอ ตรวจสอบก่อนที่จะไปข้างหน้าด้วยรหัส


8

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

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

หากแบบสอบถามย่อยนั้นจะต้องมีความสัมพันธ์กับตัวเลือกด้านนอกNOT EXISTSอาจจะดีกว่าเนื่องจากเครื่องมือเพิ่มประสิทธิภาพอาจค้นพบการทำให้เข้าใจง่ายที่ป้องกันการสร้างตารางชั่วคราวใด ๆ เพื่อทำหน้าที่เดียวกัน


6

ฉันกำลังใช้

SELECT * from TABLE1 WHERE Col1 NOT IN (SELECT Col1 FROM TABLE2)

และพบว่ามันให้ผลที่ผิด (โดยผิดฉันหมายถึงไม่มีผลลัพธ์) เนื่องจากมีค่า NULL ใน Table2.Col1

ในขณะที่เปลี่ยนแบบสอบถามเป็น

SELECT * from TABLE1 T1 WHERE NOT EXISTS (SELECT Col1 FROM TABLE2 T2 WHERE T1.Col1 = T2.Col2)

ให้ผลลัพธ์ที่ถูกต้องแก่ฉัน

ตั้งแต่นั้นมาฉันเริ่มใช้งานไม่ได้ทุกที่


5

พวกมันคล้ายกันมาก แต่ก็ไม่เหมือนกัน

ในแง่ของประสิทธิภาพฉันพบว่าการเข้าร่วมด้านซ้ายคือคำสั่งnull ที่มีประสิทธิภาพมากขึ้น (เมื่อเลือกแถวจำนวนมากนั่นคือ)


2

หากเครื่องมือเพิ่มประสิทธิภาพกล่าวว่าพวกเขาเหมือนกันให้พิจารณาปัจจัยมนุษย์ ฉันชอบที่จะเห็นไม่อยู่ :)


1

นี่เป็นคำถามที่ดีมากฉันจึงตัดสินใจเขียนบทความโดยละเอียดเกี่ยวกับหัวข้อนี้ในบล็อกของฉัน

โมเดลตารางฐานข้อมูล

สมมติว่าเรามีตารางสองตารางต่อไปนี้ในฐานข้อมูลของเราซึ่งสร้างความสัมพันธ์แบบหนึ่งต่อหลายกลุ่ม

ตาราง SQL EXISTS

studentตารางผู้ปกครองและstudent_gradeเป็นตารางเด็กเพราะมันมี student_id คอลัมน์สำคัญต่างประเทศอ้างอิง ID คอลัมน์คีย์หลักในตารางนักเรียน

student tableมีดังต่อไปนี้สองระเบียน:

| id | first_name | last_name | admission_score |
|----|------------|-----------|-----------------|
| 1  | Alice      | Smith     | 8.95            |
| 2  | Bob        | Johnson   | 8.75            |

และstudent_gradeตารางเก็บคะแนนที่นักเรียนได้รับ:

| id | class_name | grade | student_id |
|----|------------|-------|------------|
| 1  | Math       | 10    | 1          |
| 2  | Math       | 9.5   | 1          |
| 3  | Math       | 9.75  | 1          |
| 4  | Science    | 9.5   | 1          |
| 5  | Science    | 9     | 1          |
| 6  | Science    | 9.25  | 1          |
| 7  | Math       | 8.5   | 2          |
| 8  | Math       | 9.5   | 2          |
| 9  | Math       | 9     | 2          |
| 10 | Science    | 10    | 2          |
| 11 | Science    | 9.4   | 2          |

SQL ที่มีอยู่

สมมติว่าเราต้องการให้นักเรียนทุกคนที่ได้รับเกรด 10 ในวิชาคณิตศาสตร์

หากเราสนใจเฉพาะตัวระบุนักเรียนเราสามารถเรียกใช้คิวรีแบบนี้ได้:

SELECT
    student_grade.student_id
FROM
    student_grade
WHERE
    student_grade.grade = 10 AND
    student_grade.class_name = 'Math'
ORDER BY
    student_grade.student_id

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

ในการกรองstudentเรคคอร์ดที่มีเกรด 10 ในวิชาคณิตศาสตร์เราสามารถใช้ตัวดำเนินการ EXISTS SQL ดังนี้:

SELECT
    id, first_name, last_name
FROM
    student
WHERE EXISTS (
    SELECT 1
    FROM
        student_grade
    WHERE
        student_grade.student_id = student.id AND
        student_grade.grade = 10 AND
        student_grade.class_name = 'Math'
)
ORDER BY id

เมื่อเรียกใช้คิวรีด้านบนเราจะเห็นได้ว่าเฉพาะแถวอลิซเท่านั้นที่เลือก:

| id | first_name | last_name |
|----|------------|-----------|
| 1  | Alice      | Smith     |

แบบสอบถามด้านนอกเลือก studentคอลัมน์แถวที่เราสนใจกลับไปที่ลูกค้า อย่างไรก็ตามส่วนคำสั่ง WHERE กำลังใช้ตัวดำเนินการ EXISTS กับแบบสอบถามย่อยภายในที่เกี่ยวข้อง

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

แบบสอบถามย่อยภายในมีความสัมพันธ์เนื่องจากคอลัมน์ student_id ของstudent_gradeตารางตรงกับคอลัมน์ id ของตารางนักเรียนด้านนอก

SQL ไม่ใช่ EXISTS

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

ดังนั้นตัวดำเนินการ NOT EXISTS จะส่งกลับค่าจริงหากเคียวรีย่อยอ้างอิงไม่มีการบันทึก อย่างไรก็ตามหากมีการจับคู่บันทึกเดียวโดยแบบสอบถามย่อยภายในตัวดำเนินการ NOT EXISTS จะส่งกลับค่าเท็จและการดำเนินการแบบสอบถามย่อยจะหยุดลง

เพื่อให้ตรงกับบันทึกของนักเรียนทั้งหมดที่ไม่มี student_grade ที่เกี่ยวข้องกับค่าต่ำกว่า 9 เราสามารถเรียกใช้แบบสอบถาม SQL ต่อไปนี้:

SELECT
    id, first_name, last_name
FROM
    student
WHERE NOT EXISTS (
    SELECT 1
    FROM
        student_grade
    WHERE
        student_grade.student_id = student.id AND
        student_grade.grade < 9
)
ORDER BY id

เมื่อเรียกใช้แบบสอบถามข้างต้นเราจะเห็นว่ามีเพียงระเบียนของอลิซเท่านั้นที่ตรงกัน:

| id | first_name | last_name |
|----|------------|-----------|
| 1  | Alice      | Smith     |

ดังนั้นข้อดีของการใช้ตัวดำเนินการ SQL EXISTS และ NOT EXISTS ก็คือการดำเนินการแบบสอบถามย่อยภายในสามารถหยุดได้ตราบเท่าที่พบระเบียนที่ตรงกัน


-1

มันขึ้นอยู่กับ..

SELECT x.col
FROM big_table x
WHERE x.key IN( SELECT key FROM really_big_table );

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

แต่ขึ้นอยู่กับเครื่องมือเพิ่มประสิทธิภาพของ DBMS สิ่งนี้อาจไม่แตกต่างกัน

เป็นตัวอย่างเมื่อ EXISTS ดีกว่า

SELECT x.col
FROM big_table x
WHERE EXISTS( SELECT key FROM really_big_table WHERE key = x.key);
  AND id = very_limiting_criteria

1
INและEXISTS ได้รับแผนเดียวกันใน SQL Server คำถามเกี่ยวกับNOT INvs NOT EXISTSอยู่แล้ว
— Martin Smith
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.