Một số cách thức tối ưu hóa câu lệnh SQL giúp ứng dụng của bạn nhanh hơn

Trong bài viết này Stanford - Dạy kinh nghiệm lập trình sẽ chia sẻ một số cách thức tối ưu hóa thời gian chạy câu lệnh SQL giúp ứng dụng phần mềm của bạn chạy nhanh hơn, hiệu quả hơn.

Khi mới làm quen với những câu lệnh SQL để sử dụng trong lập trình thường thì chúng ta chỉ quan tâm đến việc làm sao cho chạy và ra kết quả là được. Nhưng có một thực tế khi đi làm và tham gia dự án thực tế thì đòi hỏi bạn lập trình xử lý công việc với SQL chạy được là hiển nhiên. Cái quan trọng là viết câu lệnh SQL như nào để cho tối ưu thời gian chạy, xử lý công việc nhanh hơn. Vì vậy mới có chuyện cùng một công việc được giao nhưng code của ông này lại chạy nhanh hơn ông khác. Sau đây là một số cách thức hữu ích giúp bạn viết SQL tối ưu hơn (Performance Tuning SQL) mà bạn có thể áp dụng:


Một số ví dụ được lấy để minh họa giúp cho các bạn dễ hiểu dựa trên cơ sở dữ liệu quản lý nhân viên đơn giản như lược đồ dưới:

1. Sử dụng cột chính xác cần dùng trong câu lệnh

Trong quá trình viết SQL sử dụng lệnh Select, bạn có thể liệt kê các cột dữ liệu cần lấy thay vì sử dụng kí hiệu '*' để lấy tất cả thông tin. Vì có thể bảng chứa nhiều cột và có cột bạn không sử dụng kết quả sau khi câu lệnh truy vấn đó thực hiện thành công. Như vậy nếu dùng '*' bạn vẫn lấy cột không sử dụng ra nó sẽ làm cho câu lệnh SQL của bạn thực hiện lâu hơn.

Ví dụ: Lấy các thông tin cần thiết thay vì lấy tất cả các cột trong bảng NhanVien sau:

Select MaNV, HoTen, DienThoai, Email, DiaChi from NhanVien;
--Không nên sử dụng
Select * from NhanVien;

2. Không sử dụng distinct nếu không cần thiết

Trong quá trình sử dụng câu lệnh SQL, có trường hợp bạn sẽ có nhu cầu lấy không trùng lặp một thông tin nào đó, bạn sẽ sử dụng từ khóa distinct trước cột dữ liệu. Tuy nhiên nếu cột dữ liệu nào đó trong câu lệnh SQL bạn đánh giá là không thể trùng lặp thì bạn không nên sử dụng từ khóa distinct nữa. Vì khi đó ngoài việc truy vấn lấy thông tin hệ thống sẽ phải thực hiện một phép so sánh nữa để loại bỏ các dữ liệu trùng nhau.

Ví dụ: Chúng ta sẽ sử dụng từ khóa distinct để lấy các phòng ban đã có nhân viên trong trường hợp sau:

Select distinct MaPhong from NhanVien;
--Không sử dụng distinct như câu lệnh dưới
Select distinct * from NhanVien nv join PhongBan pb on nv.MaPhong = pb.MaPhong;

3. Loại bỏ các truy vấn con (sub-query) nếu được

Khi ta sử dụng truy vấn con trong SQL, mỗi lần câu truy vấn chính thực hiện so sánh điều kiện hoặc chọn một số trường dữ liệu trả về trong truy vấn con, nó đều phải truy vấn lại câu truy vấn con và như thế là truy vấn con được thực hiện lặp lại nhiều lần. Hay nói theo độ phức tạp tính toán gọi là O(n^2). Đối với cơ sở dữ liệu lớn, thì đó thực sự là chi phí truy vấn rất lớn. Do vậy nếu trong câu lệnh SQL không cần thiết phải sử dụng truy vấn con bạn hãy loại bỏ hoặc viết theo cách thức khác cũng sẽ giúp câu lệnh SQL của bạn tối ưu hơn.

--Không nên sử dụng subquery kiểu này
Select MaPhong, TenPhong,
(Select count(*) from NhanVien where MaPhong = pb.MaPhong) as SoLuong
from PhongBan pb;
--Thay vì vậy bạn sẽ viết câu lệnh tương ứng như sau
Select MaPhong, count(*) from NhanVien
group by MaPhong;
Trong trường hợp này nếu bạn sử dụng subquery như câu lệnh đầu tiên với dữ liệu bảng nhân viên nhiều sẽ làm câu lệnh sql của bạn chậm hơn khá nhiều. Do vậy bạn nên sử dụng câu sql gộp nhóm và có thể join nếu cần lấy thông tin bảng PhongBan nữa thay vì sử dụng subquery.


4. Sử dụng inner join thay vì where hoặc cross join

Với trường hợp bạn lấy thông tin từ nhiều bảng bạn không nên sử dụng nối theo kiểu đẳng thức như ví dụ dưới đây:

Select MaNV, HoTen, DienThoai, Email, nv.MaPhong, TenPhong from NhanVien nv, PhongBan pb
where nv.MaPhong = pb.MaPhong;
Ví dụ bảng nhân viên có 1000 dòng và bảng phòng ban có 100 dòng như vậy theo cách nối này nó sẽ tạo ra 100.000 dòng trước khi lọc được 1000 dòng dữ liệu phù hợp. Cơ sở dữ liệu sẽ phải thực hiện gấp 100 lần so với mức cần thiết, gây lãng phí tài nguyên.

Thay vì vậy bạn sẽ sử dụng INNER JOIN để lấy thông tin 2 bảng trên như sau để đảm bảo câu lệnh SQL tối ưu hơn:

Select MaNV, HoTen, DienThoai, Email, nv.MaPhong, TenPhong from NhanVien nv inner join PhongBan pb
on nv.MaPhong = pb.MaPhong;

5. Sử dụng union all thay vì union

Trong câu lệnh SQL của bạn nếu sử dụng UNION ALL, truy vấn sẽ trả về tất cả các bản ghi từ cả hai bảng, bao gồm các bản ghi trùng lặp. Việc sử dụng UNION ALL sẽ giúp truy vấn thực hiện nhanh hơn so với UNION khi không cần loại bỏ các bản ghi trùng lặp.
Do vậy bạn hãy ưu tiên sử dụng UNION ALL khi bạn biết chắc dữ liệu xử lý bằng SQL mỗi dòng trong kết quả sẽ là duy nhất hoặc có thể chấp nhận việc trùng lặp.

6. Không nên sử dụng OR trong các mệnh đề nhiều điều kiện

Trong câu lệnh SQL bạn sử dụng OR trong các mệnh đề có thể làm chậm tốc độ truy vấn và khiến kết quả trả về không chính xác nếu không được sử dụng đúng cách. Thay vào đó, nên sử dụng các điều kiện AND hoặc UNION ALL để tối ưu hóa truy vấn.

Select MaNV, HoTen, DienThoai, Email, DiaChi from NhanVien
where HoTen like N'Nguyễn Văn%' OR DiaChi = N'Hà Nội';
--Có thể sử dụng thành
Select MaNV, HoTen, DienThoai, Email, DiaChi from NhanVien
where HoTen like N'Nguyễn Văn%'
Union All
Select MaNV, HoTen, DienThoai, Email, DiaChi from NhanVien
where DiaChi = N'Hà Nội';
Hy vọng qua bài viết này sẽ giúp các bạn học sql để phục vụ trong công việc, lập trình biết cách tối ưu hóa (Performance Tuning SQL) để giúp cho ứng dụng của bạn chạy nhanh hơn.

Bên cạnh đó nếu bạn đang muốn được đào tạo bài bản từ cơ bản đến nâng cao có thể tham gia ngay khóa học sql cùng chuyên gia giàu kinh nghiệm Stanford tại đây: http://bit.ly/2SLPYFF và nhận ưu đãi hấp dẫn của Stanford trong thời gian này. Bạn có thể gọi theo hotline: 0963 723 236 - 0866 586 366 để được gọi lại tư vấn trực tiếp nhé.

=============================
☎ STANFORD – ĐÀO TẠO VÀ PHÁT TRIỂN CÔNG NGHỆ
Hotline: 0963 723 236 - 0866 586 366
Website: https://stanford.com.vn
Facebook: http://bit.ly/2FN0TYb
Youtube: http://bit.ly/2TkKT7I

Tags: học sql, tối ưu câu lệnh sql, performance turning sql