Khi cần truy vấn hàng khớp **một trong nhiều giá trị** trên cùng một cột, dùng mệnh đề IN (val1, val2, ...). Cách này:
- Ngắn gọn, dễ đọc hơn chuỗi
ORdài. - Được optimizer xử lý hiệu quả (range access / index merge).
- Tránh overhead vòng lặp ứng dụng (round-trip mạng).
Ví dụ minh họa
Tạo bảng khách hàng:
mysql> CREATE TABLE DemoTable1538 (ClientId INT, ClientName VARCHAR(20));
mysql> INSERT INTO DemoTable1538 VALUES
-> (101,'Chris'), (102,'Robert'), (103,'Bob'), (104,'Adam');
Truy vấn 3 ID cùng lúc:
mysql> SELECT * FROM DemoTable1538 WHERE ClientId IN (101, 103, 104);
Kết quả:
+----------+------------+ | ClientId | ClientName | +----------+------------+ | 101 | Chris | | 103 | Bob | | 104 | Adam | +----------+------------+
So sánh 3 cách
| Cách | Ưu điểm | Nhược điểm |
|---|---|---|
| IN (..) | Tối ưu index, 1 round-trip, SQL chuẩn | Giới hạn ~1000-10000 giá trị |
OR (id=1 OR id=2...) | Linh hoạt điều kiện phức tạp | Dài, optimizer khó tối ưu, dễ lỗi logic |
| Vòng lặp app (query từng ID) | Đơn giản code app | N round-trip, chậm, tải network/DB |
Khi danh sách giá trị rất lớn (>10k)
- Tạo bảng tạm (temporary table) nạp danh sách, sau đó
JOINhoặcIN (SELECT id FROM temp). - MySQL 8.0+: dùng
VALUES ROW(1), ROW(2), ...như derived table. - Hoặc dùng
FIND_IN_SET(chậm, không dùng index).
Best practice
- Luôn ưu tiên
INcho danh sách giá trị tĩnh/động nhỏ-vừa. - Tạo index trên cột lọc (
ClientId). - Dùng prepared statement với placeholder
IN (?, ?, ?)– driver tự mở rộng (ví dụ: JDBC, MyBatis, Hibernate).