ปัญหา
การรัน SELECT หลายครั้งติดต่อกันบนตารางเดียวเพื่อดึงค่าต่างๆ ทำให้เกิด Overhead จากการ Parse, Optimize, Execute หลายรอบ
วิธีแก้: ใช้ IN() รวมเงื่อนไขใน Query เดียว
-- ❌ ช้า: Query หลายครั้ง
SELECT Name FROM DemoTable WHERE Age = 21;
SELECT Name FROM DemoTable WHERE Age = 22;
SELECT Name FROM DemoTable WHERE Age = 23;
-- ✅ เร็ว: Query ครั้งเดียว ใช้ IN()
SELECT Name FROM DemoTable WHERE Age IN (21, 22, 23);
ตัวอย่างสมบูรณ์
1. สร้างตารางและข้อมูล
CREATE TABLE DemoTable (
Id INT,
Name VARCHAR(100),
Age INT
);
INSERT INTO DemoTable VALUES (1, 'Chris', 23);
INSERT INTO DemoTable VALUES (2, 'David', 21);
INSERT INTO DemoTable VALUES (3, 'Mike', 24);
INSERT INTO DemoTable VALUES (4, 'Robert', 22);
2. Query ด้วย IN()
SELECT Name FROM DemoTable WHERE Age IN (21, 22, 23);
3. ผลลัพธ์
+--------+
| Name |
+--------+
| Chris |
| David |
| Robert |
+--------+
ประโยชน์ของการใช้ IN()
- ลด Network Round-trip - ส่ง Query ครั้งเดียว
- Optimizer ทำงานได้ดีขึ้น - วางแผน Query รวมได้
- Index ใช้งานได้เต็มที่ - Range scan บน Index เดียว
- Code สะอาดกว่า - ไม่ต้อง Loop ใน Application
เทคนิคเพิ่มเติม
ใช้กับ Subquery
SELECT * FROM Orders
WHERE CustomerId IN (SELECT Id FROM Customers WHERE Country = 'Thailand');
ร่วมกับ NOT IN (ระวังค่า NULL)
SELECT * FROM Products
WHERE CategoryId NOT IN (SELECT Id FROM Categories WHERE Active = 0);
คำเตือน: NOT IN จะคืนค่าว่างถ้า Subquery มีค่า NULL ใช้ NOT EXISTS แทนปลอดภัยกว่า
ใช้กับ Tuple (หลายคอลัมน์)
SELECT * FROM OrderItems
WHERE (OrderId, ProductId) IN ((1001, 50), (1002, 75), (1003, 80));
ข้อจำกัด
- รายการใน IN() ควรไม่เกินหลายพันค่า (แนะนำ < 1000) มิฉะนั้น Parser จะช้า
- สำหรับรายการมาก ใช้ Temporary Table หรือ JOIN แทน
สรุป
รวมหลาย SELECT ที่ต่างกันแค่ค่าใน WHERE ให้เป็น Query เดียวด้วย IN() เพื่อประสิทธิภาพและความสะอาดของโค้ด