แหล่งข้อมูลที่เชื่อถือได้ที่ <> และ! = เหมือนกันในประสิทธิภาพใน SQL Server


74

ลองพิจารณาคำตอบนี้เพื่อให้ความมั่นใจแก่ผู้ถามเกี่ยวกับ<>โอเปอเรเตอร์ที่:

<>คือ ... !=เช่นเดียวกับ

แต่จากนั้นผู้แสดงความคิดเห็นท่อขึ้นและพูดว่า:

มันเป็นความจริงที่ว่าพวกมันใช้งานได้เหมือนกัน อย่างไรก็ตามเครื่องมือเพิ่มประสิทธิภาพการใช้ SQL นั้นแตกต่างกันมาก = /! = จะถูกประเมินว่าเป็นความจริง / เท็จในขณะที่ <> หมายถึงเครื่องยนต์ต้องมองและดูว่าค่ามากกว่าหรือน้อยกว่าหมายถึงค่าใช้จ่ายในการทำงานที่มากขึ้น สิ่งที่ควรพิจารณาเมื่อเขียนข้อความค้นหาที่อาจมีราคาแพง

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

คำตอบ:


144

ระหว่างการวิเคราะห์คำ SQL Server sqllang!DecodeCompOpจะเรียกเพื่อกำหนดชนิดของตัวดำเนินการเปรียบเทียบที่มีอยู่:

เรียกสแตก

สิ่งนี้เกิดขึ้นได้ดีก่อนที่ทุกสิ่งในเครื่องมือเพิ่มประสิทธิภาพจะเกี่ยวข้อง

จากผู้ประกอบการเปรียบเทียบ (Transact-SQL)

ตัวดำเนินการเปรียบเทียบและความหมาย

ติดตามรหัสโดยใช้ดีบักเกอร์และสัญลักษณ์สาธารณะ * sqllang!DecodeCompOpส่งคืนค่าใน register eax** ดังนี้:

╔════╦══════╗
║ Op ║ Code ║
╠════╬══════╣
║ <  ║    1 ║
║ =  ║    2 ║
║ <= ║    3 ║
║ !> ║    3 ║
║ >  ║    4 ║
║ <> ║    5 ║
║ != ║    5 ║
║ >= ║    6 ║
║ !< ║    6 ║
╚════╩══════╝

!=และ<>ทั้งคู่ส่งคืน 5 ดังนั้นจะแยกไม่ออกในการดำเนินการในภายหลังทั้งหมด (รวมถึงการรวบรวม & การเพิ่มประสิทธิภาพ)


แม้ว่ารองไปยังจุดดังกล่าวข้างต้นก็ยังเป็นไปได้ (เช่นการใช้สถานะการสืบค้นกลับไม่มีเอกสาร 8605) จะมองไปที่ต้นไม้ตรรกะส่งผ่านไปยังเพิ่มประสิทธิภาพในการยืนยันว่าทั้งสอง!=และ<>แมปไปScaOp_Comp x_cmpNe(ไม่เท่ากันเกลาเปรียบเทียบประกอบการ)

ตัวอย่างเช่น:

SELECT P.ProductID FROM Production.Product AS P
WHERE P.ProductID != 4
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8605);

SELECT P.ProductID FROM Production.Product AS P
WHERE P.ProductID <> 4
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8605);

ทั้งผลิต:

LogOp_Project QCOL: [P] .ProductID
    LogOp_Select
        LogOp_ รับ TBL: การผลิตผลิตภัณฑ์ (นามแฝง TBL: P)
        ScaOp_Comp x_cmpNe
            ScaOp_Identifier QCOL: [P] .ProductID
            ScaOp_Const TI (int, ML = 4) XVAR (int, ไม่ได้เป็นเจ้าของ, ค่า = 4)
    AncOp_PrjList 

เชิงอรรถ

* ฉันใช้WinDbg ; debuggers อื่น ๆ ที่มีอยู่ สัญลักษณ์สาธารณะมีให้บริการผ่านเซิร์ฟเวอร์สัญลักษณ์ Microsoft ปกติ สำหรับข้อมูลเพิ่มเติมดูลึกลงไปใน SQL Server โดยใช้ Minidumpsโดยทีมที่ปรึกษาลูกค้าSQL ServerและSQL Server Debugging ด้วย WinDbg - คำแนะนำโดย Klaus Aschenbrenner

** การใช้ EAX บนอนุพันธ์ของ Intel แบบ 32 บิตสำหรับค่าส่งคืนจากฟังก์ชันนั้นเป็นเรื่องปกติ แน่นอนว่า Win32 ABI ทำอย่างนั้นและฉันค่อนข้างมั่นใจว่ามันสืบทอดการฝึกฝนตั้งแต่สมัยโบราณใน MS-DOS ซึ่ง AX ใช้เพื่อจุดประสงค์เดียวกัน - Michael Kjörling


58

ฉันทำงานที่ Microsoft ในการสนับสนุน SQL และฉันถาม Jack Li, วิศวกรการเลื่อนระดับอาวุโสและผู้เชี่ยวชาญเรื่องเรื่องประสิทธิภาพของ SQL Server, "SQL ปฏิบัติต่อ! = สิ่งใดแตกต่างจาก <> หรือไม่" และเขาก็พูดว่า "พวกเขาเหมือนกัน"


8

ฉันคิดว่าข้อพิสูจน์ต่อไปนี้<>ไม่ได้ทำการเปรียบเทียบ 2 อย่าง

  1. SQL Standard 92 กำหนด<>เป็นตัวดำเนินการไม่เท่ากับ ( http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt ) ในทางเทคนิคแล้ว!=เป็นส่วนขยายของมาตรฐาน (แม้ว่าฉันจะไม่สามารถคิดถึง RDBMS ใด ๆ ที่ไม่ได้ใช้งานได้)
  2. ถ้า SQLServer ถือว่า<>เป็นโอเปอเรเตอร์ 2 ตัวไม่ใช่หนึ่งตัวมันจะทำเช่นเดียวกันกับ><ที่อยู่ในข้อผิดพลาดทางไวยากรณ์

1

ไม่ถูกต้อง Books Online (BOL) กล่าวว่าพวกเขาใช้งานได้เหมือนกัน:

! = (ไม่เท่ากับ) (Transact-SQL)

และถ้าคุณดูที่แผนการดำเนินการที่!=ถูกนำมาใช้ภายใต้คำกริยาก็เปลี่ยนแปลง ไป!=<>


2
ปัญหาคือว่าภาษา "หน้าที่เหมือนกัน" ได้รับการยอมรับแล้วในความคิดเห็นอ้างอิง แต่ทำให้ความแตกต่างเพิ่มเติมเกี่ยวกับประสิทธิภาพแม้ว่าคุณและความรู้ของฉันว่า "หน้าที่เหมือนกัน" รวมถึงวิธีการใช้งานจริงและลักษณะการทำงานใด ๆ หากมีใครจะไปพิสูจน์เรื่องนี้เกินกว่าความสงสัยที่กำหนดไว้ใครจะทำอะไร?
ErikE
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.