- vừa được xem lúc

Thứ tự thực thi câu SQL

0 0 1

Người đăng: Bảo Võ

Theo Viblo Asia

🎯 Mở đầu

Ngày nay, hầu hết các framework hiện đại đều hỗ trợ ORM. Cụ thể như Laravel có Eloquent – một công cụ mạnh mẽ và cực kỳ tiện lợi. Nhưng chính sự “dễ dùng” ấy lại dễ khiến ta quên mất một điều cốt lõi: đằng sau là những câu SQL đang được thực thi.

Nếu không hiểu bản chất của SQL, ta có thể viết ra những truy vấn chạy được nhưng lại không tối ưu. Có lúc chúng ta bối rối vì không hiểu tại sao một câu truy vấn lại chậm, hoặc sửa tới sửa lui mà vẫn không đạt được kết quả mong muốn.

Hôm nay, mình chia sẻ một vài trải nghiệm về thứ tự thực thi SQL – một kiến thức tưởng chừng đơn giản, nhưng nếu nắm vững thì sẽ giúp bạn chủ động hơn rất nhiều khi viết và tối ưu truy vấn.


❓ Những câu hỏi thường gặp

  • Một câu SQL thực thi theo thứ tự nào?
  • Tại sao đã dùng LIMIT mà truy vấn vẫn chậm?
  • Vì sao không thể dùng alias trong WHERE?
  • Nên đặt điều kiện lọc trong ON của JOIN hay trong WHERE?

🧠 Thứ tự thực hiện một câu SQL

Nhìn vào cú pháp:

SELECT ... FROM ... WHERE ...

...nhiều người dễ nghĩ rằng SQL sẽ xử lý tuần tự theo cách viết: SELECTFROMWHERE. Nhưng thực tế, SQL là ngôn ngữ khai báo (declarative), không phải ngôn ngữ thủ tục.

Câu truy vấn bạn viết ra sẽ được DBMS (Hệ quản trị CSDL) chuyển đổi và thực thi theo thứ tự logic sau:

1. FROM
2. ON
3. JOIN
4. WHERE
5. GROUP BY
6. HAVING
7. SELECT
8. DISTINCT
9. ORDER BY
10. LIMIT (TOP)

Hiểu thứ tự này là nền tảng để lý giải nhiều vấn đề hiệu năng.


🐌 Vì sao truy vấn chậm dù đã dùng LIMIT?

Ví dụ đoạn code Eloquent:

User::where('status', 1) ->orderBy('created_at', 'desc') ->limit(10) ->get();

Câu lệnh trên hoàn toàn đúng cú pháp, nhưng khi áp dụng với bảng users có 2 triệu records, bạn sẽ thấy tốc độ truy vấn khá chậm.

Lý do: LIMIT chỉ được áp dụng sau khi dữ liệu đã được lọc và sắp xếp xong. Nếu bạn sắp xếp (ORDER BY) theo một cột không nằm trong index, hệ thống phải sort toàn bộ tập dữ liệu trước, rồi mới chọn ra 10 records đầu tiên.

👉 Để LIMIT hiệu quả hơn:

  • Tránh ORDER BY nếu không thực sự cần thiết.
  • Nếu cần sắp xếp, hãy đảm bảo cột đó đã được index đúng cách.

🚫 Vì sao không thể gọi alias trong WHERE?

SELECT price * quantity AS total
FROM orders
WHERE total > 1000;

Câu trên sẽ gây lỗi. Vì sao?

WHERE được thực hiện trước SELECT, nên alias total chưa được tạo ra tại thời điểm đó.

Tuy nhiên, nếu viết:

SELECT price * quantity AS total
FROM orders
ORDER BY total DESC;

...thì lại chạy bình thườngORDER BY được thực hiện sau SELECT, lúc này alias đã tồn tại.

💡 Ghi nhớ: Alias chỉ dùng được ở các bước sau SELECT, như ORDER BY hay HAVING.


⚖️ Điều kiện nên để trong ON hay WHERE?

Giả sử bạn viết:

SELECT ...
FROM orders o
JOIN users u ON o.user_id = u.id AND u.status = 1

So với:

SELECT ...
FROM orders o
JOIN users u ON o.user_id = u.id
WHERE u.status = 1

Về mặt logic, kết quả giống nhau. Nhưng về hiệu năng, thì lại khác nhau đáng kể.

  • Điều kiện đặt trong ON sẽ lọc dữ liệu ngay trong quá trình JOIN, giảm lượng dữ liệu trung gian.
  • Điều kiện đặt trong WHERE sẽ lọc sau khi JOIN xong, khiến hệ thống phải xử lý thêm dữ liệu không cần thiết.

👉 Kinh nghiệm cá nhân: Luôn ưu tiên lọc sớm – giảm tải sớm. Nhất là khi JOIN nhiều bảng lớn, tối ưu từng bước là điều cần thiết.


🔍 Với query phức tạp thì sao?

Trong những truy vấn lồng nhau (subquery), thỉnh thoảng hay gặp tình huống là dồn hết điều kiện vào WHERE ở bên ngoài.

NÊN LÀ : tối ưu từ trong ra ngoài, thu hẹp tập dữ liệu trong từng truy vấn con. Mỗi subquery càng nhỏ, càng cụ thể thì DBMS càng dễ tối ưu.


🧾 Kết luận

ORM như Eloquent giúp chúng ta viết code nhanh chóng và dễ đọc hơn. Nhưng đừng quên rằng mỗi câu Eloquent bạn viết đều sẽ được dịch ra SQL – và nếu bạn không hiểu rõ cơ chế thực thi, bạn đang viết SQL một cách "vô thức", phó mặc hiệu năng cho framework xử lý.

Để viết một câu SQL tốt, bạn nên:

  1. Nắm vững thứ tự thực thi SQL.
  2. Viết truy vấn sao cho lọc được tập dữ liệu nhỏ nhất càng sớm càng tốt.

✌️ Cảm ơn bạn đã đọc đến đây

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Stored Procedure trong SQL Server

Stored Procedure là 1 phần không thể thiếu của SQL Server. Chúng có thể hỗ trợ rất nhiều cho lập trình và cấu hình cơ sở dữ liệu.

0 0 171

- vừa được xem lúc

sử dụng index trong sql query

Index là một trong những yếu tố quan trọng nhất góp phần vào việc nâng cao hiệu suất của cơ sở dữ liệu. Index trong SQL tăng tốc độ của quá trình truy vấn dữ liệu bằng cách cung cấp phương pháp truy xuất nhanh chóng tới các dòng trong các bảng, tương tự như cách mà mục lục của một cuốn sách giúp bạn

0 0 273

- vừa được xem lúc

Hướng dẫn sửa lỗi không cài được SQL Server

Hôm qua do yêu cầu môn học, mình có cài lại Microsoft SQL Server. Trước đó mình có cài rồi, nhưng rồi lâu không dùng nên gỡ ra cho nhẹ máy. Bây giờ có dịp cần nên mình mới cài lại. Chi tiết lỗi mình gặp phải.

0 0 143

- vừa được xem lúc

Bạn nên tránh sử dụng Soft Delete khi có thể, và đây là lý do tại sao

Con người luôn luôn mắc sai lầm. Vì vậy, việc "lo xa" trước mọi tình huống xấu nhất chưa bao giờ là thừa.

0 0 212

- vừa được xem lúc

Sử dụng trigger trong SQL qua ví dụ cơ bản.

Trigger là gì . Cú pháp của Trigger. CREATE TRIGGER tên_trigger ON tên_bảng. FOR {DELETE, INSERT, UPDATE}.

0 0 172

- vừa được xem lúc

Khác biệt giữa khóa chính và khóa ngoại trong SQL

Các khoá chính và khóa ngoại là hai loại ràng buộc có thể được sử dụng để thực thi toàn vẹn dữ liệu trong các bảng SQL Server và đây là những đối tượng cơ sở dữ liệu quan trọng. Trong bài này, tôi muố

0 0 160