Концептуальный вопрос: быстрее ли отдельные запросы, чем объединения, или: я должен попытаться сжать каждую информацию, которую я хочу на стороне клиента, в один оператор SELECT или просто использовать столько, сколько кажется удобным?
TL; DR : если мой присоединенный запрос занимает больше времени, чем выполнение отдельных запросов, это моя ошибка или это следует ожидать?
Во-первых, я не очень разбираюсь в базе данных, так что это может быть только я, но я заметил, что, когда мне нужно получить информацию из нескольких таблиц, «часто» быстрее получить эту информацию с помощью нескольких запросов к отдельным таблицам (может быть, содержит простое внутреннее соединение) и соединяет данные вместе на стороне клиента, чтобы попытаться написать (сложный) объединенный запрос, где я могу получить все данные в одном запросе.
Я попытался собрать один чрезвычайно простой пример:
Настройка схемы :
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);
Запрос A :
select NAME from MASTER
where ID = 1
| NAME |
--------
| One |
Запрос Б :
select ID, VALUE from DATA
where MASTER_ID = 1
| ID | VALUE |
--------------
| 1 | 1.3 |
| 2 | 1.5 |
| 3 | 1.7 |
Запрос 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
| NAME | ID | VALUE |
---------------------
| One | 1 | 1.3 |
| One | 2 | 1.5 |
| One | 3 | 1.7 |
Конечно, я не измерял с ними какую-либо производительность, но можно наблюдать:
- Запрос A + B возвращает то же количество полезной информации, что и запрос C.
- A + B должен вернуть клиенту 1 + 2x3 == 7 «ячеек данных»
- C должен вернуть клиенту 3x3 == 9 «ячеек данных», потому что при объединении я естественно включаю некоторую избыточность в набор результатов.
Обобщая из этого (насколько это возможно):
Объединенный запрос всегда должен возвращать больше данных, чем отдельные запросы, которые получают одинаковое количество информации. Поскольку база данных должна объединять данные, для больших наборов данных можно предположить, что база данных должна выполнять больше работы над одним объединенным запросом, чем над отдельными, поскольку (по крайней мере) она должна возвращать больше данных клиенту.
Из этого следует, что когда я наблюдаю, что разбиение запроса на стороне клиента на несколько запросов дает лучшую производительность, это просто путь, или это скорее означает, что я испортил объединенный запрос?