ขณะอ่านเอกสารเกี่ยวกับการปรับแต่ง SQL ฉันพบสิ่งนี้:
SELECT COUNT(*)
:
- นับจำนวนแถว
- มักใช้อย่างไม่เหมาะสมเพื่อตรวจสอบการมีอยู่ของระเบียน
คือSELECT COUNT(*)
จริงๆที่ไม่ดีที่?
วิธีที่เหมาะสมในการตรวจสอบการมีอยู่ของบันทึกคืออะไร?
ขณะอ่านเอกสารเกี่ยวกับการปรับแต่ง SQL ฉันพบสิ่งนี้:
SELECT COUNT(*)
:
คือSELECT COUNT(*)
จริงๆที่ไม่ดีที่?
วิธีที่เหมาะสมในการตรวจสอบการมีอยู่ของบันทึกคืออะไร?
คำตอบ:
ควรใช้วิธีใดวิธีหนึ่งต่อไปนี้:
-- Method 1.
SELECT 1
FROM table_name
WHERE unique_key = value;
-- Method 2.
SELECT COUNT(1)
FROM table_name
WHERE unique_key = value;
ทางเลือกแรกไม่ควรให้ผลลัพธ์หรือผลลัพธ์เดียวการนับครั้งที่สองควรเป็นศูนย์หรือหนึ่งรายการ
เอกสารที่คุณใช้อยู่มีอายุเท่าไหร่ แม้ว่าคุณจะได้อ่านคำแนะนำที่ดี แต่ตัวเพิ่มประสิทธิภาพการสืบค้นส่วนใหญ่ในการปรับให้เหมาะสมที่สุดของ RDBMS SELECT COUNT(*)
อยู่แล้วดังนั้นแม้ว่าจะมีความแตกต่างในทางทฤษฎี (และฐานข้อมูลเก่า) แต่คุณไม่ควรสังเกตเห็นความแตกต่างในทางปฏิบัติ
ฉันไม่ต้องการใช้ฟังก์ชัน Count เลย:
IF [NOT] EXISTS ( SELECT 1 FROM MyTable WHERE ... )
<do smth>
ตัวอย่างเช่นหากคุณต้องการตรวจสอบว่ามีผู้ใช้อยู่ก่อนที่จะแทรกลงในฐานข้อมูลหรือไม่แบบสอบถามสามารถมีลักษณะดังนี้:
IF NOT EXISTS ( SELECT 1 FROM Users WHERE FirstName = 'John' AND LastName = 'Smith' )
BEGIN
INSERT INTO Users (FirstName, LastName) VALUES ('John', 'Smith')
END
คุณสามารถใช้ได้:
SELECT 1 FROM MyTable WHERE <MyCondition>
ถ้าไม่มีระเบียนที่ตรงกับเงื่อนไขชุดระเบียนที่ได้จะว่างเปล่า
คำตอบอื่น ๆ ค่อนข้างดี แต่มันจะมีประโยชน์ในการเพิ่มLIMIT 1
(หรือเทียบเท่าเพื่อป้องกันการตรวจสอบแถวที่ไม่จำเป็น
SELECT COUNT(1) FROM MyTable WHERE ...
จะวนซ้ำผ่านระเบียนทั้งหมด นี่คือเหตุผลที่ไม่ดีที่จะใช้สำหรับการบันทึก
ฉันจะใช้
SELECT TOP 1 * FROM MyTable WHERE ...
หลังจากค้นหา 1 ระเบียนมันจะยุติการวนซ้ำ
SELECT TOP 1
มันจะยุติจริง ๆ หลังจากการค้นหาหนึ่งหรือมันจะยังคงหาทั้งหมดที่จะบอกว่าเป็นที่หนึ่ง TOP?
IF EXISTS (SELECT TOP 1 1 FROM ... WHERE ..)
คุณสามารถใช้ได้:
SELECT COUNT(1) FROM MyTable WHERE ...
หรือ
WHERE [NOT] EXISTS
( SELECT 1 FROM MyTable WHERE ... )
สิ่งนี้จะมีประสิทธิภาพมากกว่าที่SELECT *
คุณเพียงแค่เลือกค่า 1 สำหรับแต่ละแถวแทนที่จะเป็นฟิลด์ทั้งหมด
นอกจากนี้ยังมีความแตกต่างเล็กน้อยระหว่าง COUNT (*) และ COUNT (ชื่อคอลัมน์):
COUNT(*)
จะนับแถวทั้งหมดรวมถึงโมฆะCOUNT(column name)
จะนับเฉพาะชื่อคอลัมน์ที่ไม่เป็นโมฆะเท่านั้นcount(1)
และcount(*)
จะแตกต่างกันใน DBMS ที่ทำให้สมองตายที่สุดเท่านั้น
count(*)
count(1)
ไม่ว่าจะเป็นกรณีสำหรับDBMS อื่น ๆฉันไม่สามารถพูดได้
คุณสามารถใช้ได้:
SELECT 1 FROM MyTable WHERE... LIMIT 1
ใช้select 1
เพื่อป้องกันการตรวจสอบฟิลด์ที่ไม่จำเป็น
ใช้LIMIT 1
เพื่อป้องกันการตรวจสอบแถวที่ไม่จำเป็น
ฉันใช้วิธีนี้:
IIF(EXISTS (SELECT TOP 1 1
FROM Users
WHERE FirstName = 'John'), 1, 0) AS DoesJohnExist
ตัวเลือกอื่น ๆ :
SELECT CASE
WHEN EXISTS (
SELECT 1
FROM [MyTable] AS [MyRecord])
THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END