JOIN vs Query + For – Hiệu suất Query

Hiệu suất query trong MySQL giữa 2 trường hợp sau

Trường hợp 1: kết nối 2 bảng không điều kiện để đáp ứng 1 au.id bảng admin_users sẽ tương ứng với toàn bộ bản ghi trong bảng rate_capacity_criterias Query JOIN không điều kiện như sau: SELECT au.id as user_id, cri.name as cri_name FROM admin_users as au JOIN rate_capacity_criterias as cri;

Trường hợp 2: Query toàn bộ bảng admin_users. Query toàn bộ bảng rate_capacity_criterias. Sử dụng vòng foreach trong code PHP kết quả 2 query trên để kết hợp dữ liệu đáp ứng điều kiện 1 au.id bảng admin_users sẽ tương ứng với toàn bộ bản ghi trong bảng rate_capacity_criterias.

Trong trường hợp này, truy vấn thứ nhất (trường hợp 1) sẽ hiệu quả hơn. Việc sử dụng JOIN để kết nối 2 bảng sẽ cho phép hệ quả trả về sớm hơn so với việc truy vấn riêng lẻ 2 bảng và sử dụng vòng lặp để kết hợp chúng.

Việc sử dụng JOIN cũng giảm thiểu số lần truy vấn và truy xuất dữ liệu từ ổ đĩa, do đó cải thiện hiệu suất truy vấn của ứng dụng. Nếu id được index trong cả 2 bảng, việc kết nối sẽ được thực hiện nhanh chóng và hiệu quả hơn.

Giả định dữ liệu

Đối với giả định dữ liệu bảng admin_users: 5.000.000 records và bảng rate_capacity_criterias: 1.000 records hiệu suất áp dụng 2 trường hợp trên thì trường hợp nào hiệu suất tốt hơn. Lưu ý: tất cả dữ liệu truy vấn đã được index.

Trường hợp 1 sử dụng JOIN sẽ hiệu suất cao hơn trường hợp 2 sử dụng vòng foreach để kết hợp dữ liệu.

Bởi vì trong:

Trường hợp 1: dữ liệu được lấy trực tiếp từ cơ sở dữ liệu thông qua một truy vấn và các bản ghi phù hợp được lấy trong một lần truy vấn.

Trường hợp 2: cần phải thực hiện hai truy vấn riêng biệt và sau đó kết hợp dữ liệu trong code PHP thông qua vòng lặp foreach, điều này có thể mất nhiều thời gian và tài nguyên hơn.

Trong giả định dự liệu này, vì số lượng bản ghi của bảng rate_capacity_criterias là nhỏ (1.000 records), nên hiệu suất giữa hai trường hợp có thể không khác biệt quá nhiều. Tuy nhiên, nếu số lượng bản ghi của bảng rate_capacity_criterias tăng lên đáng kể, thì sử dụng JOIN sẽ hiệu suất hơn và tránh được việc phải thực hiện nhiều truy vấn trong trường hợp 2.

Kiểm tra thực tế

Dữ liệu kiểm tra đầu vào bảng admin_users: 3.841 records và rate_capacity_criterias: 125 records.

Thời gian thực thi trường hợp 1:

SELECT au.id,au.username,cri.name FROM admin_users as au
JOIN rate_capacity_criterias as cri
ON cri.id!=0;
/*[CROSS JOIN] Điều kiện on cri.id!=0 là join không điều kiện (Cartesian Product), hay điều khiện không bao giờ xảy ra để gộp (tích 3.841*125) cả 2 bảng: admin_users + rate_capacity_criterias*/

Thời gian: 480.125 total, Query took 0.0006 seconds.

Thời gian thực thi trường hợp 2:

SELECT au.id, au.username FROM admin_users as au;

Thời gian: 3.841 total, Query took 0.0006 seconds.

SELECT cri.name FROM rate_capacity_criterias as cri;

Thời gian: 125 total, Query took 0.0004 seconds.

Ở trường hợp này sau khi có kết quả query (query took), sau đó trên code PHP hoặc ngôn ngữ sử dụng khác chúng ta cần xử lý vòng lặp để kết hợp các kết quả trên nữa. Chắc chắn một điểm là lặp qua 3.841 kết quả + join với 125 thì cần một khoảng thời gian xử lý để có kết quả cuối cùng.

Trong khi đó ở trường hợp 1 kết quả và thời gian hoàn toàn thể hiện hiệu suất tốt hơn rất nhiều.

Lưu ý: giá trị query took chỉ mang tính tham khảo tương đối, để có thêm thông tin về thời gian thực thi query có thể sử dụng các công cụ hỗ trợ khác, ví dụ như Heideli, MySQLWorkBench,… những ứng dụng này có nhiều tiện ích để kiểm thử và theo dõi thông tin liên quan tới query.