+1

Mệnh đề WHERE: "Người gác cổng" quyền năng và những bí thuật lọc dữ liệu đỉnh cao

1. Bản chất của WHERE: Lọc từ gốc

Như mình đã nhắc ở bài trước, mệnh đề WHERE được thực thi ngay sau FROM. Điều này có nghĩa là Database sẽ lọc các dòng thỏa mãn điều kiện trước khi chọn ra các cột (SELECT) hay sắp xếp (ORDER BY).

Việc lọc càng sớm, lượng dữ liệu phải xử lý ở các bước sau càng ít. Đó là lý do tại sao WHERE là "chìa khóa" đầu tiên của hiệu năng.

2. "Biệt đội" toán tử so sánh

Đừng chỉ dùng mỗi dấu =, SQL cung cấp cho bạn một kho vũ khí cực kỳ đa dạng:

Toán tử Ý nghĩa Ví dụ
= Bằng status = 'active'
<> hoặc != Khác/Không bằng role <> 'admin'
>, < Lớn hơn, Nhỏ hơn price > 100
>=, <= Lớn hơn hoặc bằng... age >= 18
BETWEEN Nằm trong khoảng (bao gồm biên) salary BETWEEN 1000 AND 2000
IN Nằm trong một danh sách city IN ('Hanoi', 'Saigon')
IS NULL Kiểm tra giá trị rỗng deleted_at IS NULL

3. Logic phức tạp: Sự kết hợp giữa AND, OR và NOT

Khi một điều kiện là chưa đủ, chúng ta dùng các toán tử logic để "siết chặt" bộ lọc:

  • AND: Tất cả phải đúng. (Ưu tiên dùng vì nó thu hẹp tập dữ liệu rất nhanh).
  • OR: Chỉ cần một cái đúng. (Cẩn thận: Dùng quá nhiều OR trên các cột khác nhau dễ làm Database "bối rối" và bỏ qua Index).
  • NOT: Đảo ngược điều kiện.

Lưu ý về độ ưu tiên: AND luôn được ưu tiên chạy trước OR. Nếu bạn có một câu query phức tạp, hãy luôn dùng dấu ngoặc đơn () để nhóm các điều kiện lại, tránh việc Database hiểu lầm ý bạn.

4. Pattern Matching với LIKE: Sức mạnh và Nguy hiểm

LIKE cho phép bạn tìm kiếm theo khuôn mẫu (pattern) bằng các ký tự đại diện:

  • %: Đại diện cho một chuỗi ký tự bất kỳ (độ dài 0 hoặc nhiều hơn).
  • _: Đại diện cho đúng 1 ký tự duy nhất.

Cảnh báo "bay màu" hiệu năng: * WHERE name LIKE 'Hoang%': Ổn, vì Database vẫn có thể dùng Index để tìm các tên bắt đầu bằng "Hoang".

WHERE name LIKE '%Hoang%': Rất tệ! Dấu % ở đầu khiến Database không thể dùng Index (B-Tree), buộc nó phải quét toàn bộ bảng (Full Table Scan).

5. "Bí thuật" SARGable: Viết WHERE sao cho nhanh?

Đây là khái niệm phân biệt giữa Dev "xịn" và Dev "thường". SARGable (Search ARGumentable) nghĩa là viết điều kiện sao cho Database có thể tận dụng được Index.

  • Không SARGable (Chậm): WHERE YEAR(created_at) = 2026
  • Lý do: Database phải chạy hàm YEAR() cho từng dòng một rồi mới so sánh. Index bị vô hiệu hóa hoàn toàn.
  • SARGable (Nhanh): WHERE created_at >= '2026-01-01' AND created_at <= '2026-12-31'
  • Lý do: Database so sánh trực tiếp giá trị cột với hằng số, Index hoạt động trơn tru.

6. Cạm bẫy với giá trị NULL

Nhớ kỹ: NULL không phải là một giá trị, nó là "trạng thái trống". Bạn không thể dùng WHERE status = NULL.

  • Sai: WHERE status = NULL (Kết quả luôn là rỗng).
  • Đúng: WHERE status IS NULL hoặc WHERE status IS NOT NULL.

Lời kết

Mệnh đề WHERE là công cụ mạnh nhất để bạn kiểm soát dữ liệu. Hãy nhớ 3 quy tắc vàng: Lọc sớm, dùng đúng toán tử và luôn giữ cho điều kiện SARGable.

Hy vọng bài viết này giúp "bố đời" Huy Hoàng viết được những câu query "sắc lẹm", lọc đâu trúng đó mà server Hasaki vẫn chạy phăm phăm!

Ở bài tới, mình sẽ dắt anh em đi sâu vào một chủ đề "hack não" hơn: Logical Operators & Truth Tables - Tại sao 1 + 1 trong SQL không phải lúc nào cũng bằng 2?

Anh em đã từng gặp case nào query WHERE chạy 10 phút không ra kết quả chưa? Hãy chia sẻ "chiến tích" hoặc cách bạn đã tối ưu nó ở bên dưới nhé!

Đừng quên Upvote nếu thấy bài viết này hữu ích cho sự nghiệp Backend của mình!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí