Câu hỏi về khái niệm: Các truy vấn cá nhân có nhanh hơn tham gia không, hoặc: Tôi có nên cố gắng ép mọi thông tin tôi muốn ở phía máy khách vào một câu lệnh CHỌN hay chỉ sử dụng nhiều như có vẻ thuận tiện?
TL; DR : Nếu truy vấn đã tham gia của tôi mất nhiều thời gian hơn so với chạy các truy vấn riêng lẻ, đây có phải là lỗi của tôi không hoặc đây có phải là dự kiến không?
Đầu tiên, tôi không rành về cơ sở dữ liệu, nên có thể chỉ là tôi, nhưng tôi nhận thấy rằng khi tôi phải lấy thông tin từ nhiều bảng, thì "thường" nhanh hơn để có được thông tin này qua nhiều truy vấn trên các bảng riêng lẻ (có thể chứa một phép nối bên trong đơn giản) và vá dữ liệu lại với nhau ở phía máy khách để cố gắng viết một truy vấn đã tham gia (phức tạp) trong đó tôi có thể nhận được tất cả dữ liệu trong một truy vấn.
Tôi đã cố gắng kết hợp một ví dụ cực kỳ đơn giản:
Cài đặt lược đồ :
CREATE TABLE MASTER
( ID INT NOT NULL
, NAME VARCHAR2(42 CHAR) NOT NULL
, CONSTRAINT PK_MASTER PRIMARY KEY (ID)
);
CREATE TABLE DATA
( ID INT NOT NULL
, MASTER_ID INT NOT NULL
, VALUE NUMBER
, CONSTRAINT PK_DATA PRIMARY KEY (ID)
, CONSTRAINT FK_DATA_MASTER FOREIGN KEY (MASTER_ID) REFERENCES MASTER (ID)
);
INSERT INTO MASTER values (1, 'One');
INSERT INTO MASTER values (2, 'Two');
INSERT INTO MASTER values (3, 'Three');
CREATE SEQUENCE SEQ_DATA_ID;
INSERT INTO DATA values (SEQ_DATA_ID.NEXTVAL, 1, 1.3);
INSERT INTO DATA values (SEQ_DATA_ID.NEXTVAL, 1, 1.5);
INSERT INTO DATA values (SEQ_DATA_ID.NEXTVAL, 1, 1.7);
INSERT INTO DATA values (SEQ_DATA_ID.NEXTVAL, 2, 2.3);
INSERT INTO DATA values (SEQ_DATA_ID.NEXTVAL, 3, 3.14);
INSERT INTO DATA values (SEQ_DATA_ID.NEXTVAL, 3, 3.7);
Truy vấn A :
select NAME from MASTER
where ID = 1
Kết quả :
| NAME |
--------
| One |
Truy vấn B :
select ID, VALUE from DATA
where MASTER_ID = 1
Kết quả :
| ID | VALUE |
--------------
| 1 | 1.3 |
| 2 | 1.5 |
| 3 | 1.7 |
Truy vấn C :
select M.NAME, D.ID, D.VALUE
from MASTER M INNER JOIN DATA D ON M.ID=D.MASTER_ID
where M.ID = 1
Kết quả :
| NAME | ID | VALUE |
---------------------
| One | 1 | 1.3 |
| One | 2 | 1.5 |
| One | 3 | 1.7 |
Tất nhiên, tôi không đo bất kỳ hiệu suất nào với những thứ này, nhưng người ta có thể quan sát:
- Truy vấn A + B trả về cùng một lượng thông tin có thể sử dụng như Truy vấn C.
- A + B phải trả lại 1 + 2x3 == 7 "Ô dữ liệu" cho máy khách
- C phải trả lại 3x3 == 9 "Ô dữ liệu" cho máy khách, vì với phép nối, tôi tự nhiên bao gồm một số dự phòng trong tập kết quả.
Tổng quát hóa từ điều này (càng xa càng tốt):
Một truy vấn đã tham gia luôn phải trả về nhiều dữ liệu hơn các truy vấn riêng lẻ nhận cùng một lượng thông tin. Do cơ sở dữ liệu phải kết hợp dữ liệu với nhau, nên đối với các bộ dữ liệu lớn, người ta có thể giả định rằng cơ sở dữ liệu phải thực hiện nhiều công việc hơn trên một truy vấn đã tham gia so với các truy vấn riêng lẻ, vì (ít nhất) nó phải trả lại nhiều dữ liệu hơn cho máy khách.
Liệu nó có tuân theo điều này không, khi tôi quan sát rằng việc tách một truy vấn phía máy khách thành nhiều truy vấn mang lại hiệu suất tốt hơn, đây chỉ là cách để đi, hay nó có nghĩa là tôi đã làm rối tung truy vấn đã tham gia?