оптимизация запроса

Viacheslav_mihalich
Дата: 25.01.2013 14:25:21
Доброго дня!

есть 2 таблицы:
cl
---------------------
id | o_t_id
---------------------

o_t_ids
---------------------
id | name
---------------------

o_t_id (может быть NULL) - внешний ключ таблицы o_t_ids.

нужно выбрать из таблицы cl все записи, где вместо внешнего ключа таблицы o_t_id показать соответствующее имя из таблицы o_t_ids.

следующий запрос неверен, т.к. не выбираются записи с o_t_id is NULL:

SELECT cl.id, o_t_ids.name
FROM cl, o_t_ids    
WHERE cl.o_t_id = o_t_ids.id;


следующий запрос верный, но приходится использовать внутренние подзапросы:

SELECT cl.id, (SELECT name FROM o_t_ids WHERE  o_t_ids.id = cl.o_t_id)
FROM cl;


Вопрос: можно ли получить искомый результат одним запросом, не используя внутренних подзапросов?
Или все же правильно использовать последний вариант?

В связи с чем такой может быть глуповатый вопрос:
В боевой базе я использую большой запрос со множеством внутренних подзапросов.
Хотелось бы оптимизировать и ускорить процесс.
tanglir
Дата: 25.01.2013 15:00:04
Viacheslav_mihalich
не выбираются записи с o_t_id is NULL
left join
Viacheslav_mihalich
Дата: 25.01.2013 20:04:46
Однозначно спасибо за совет.
выражение:

SELECT cl.id, o_t_ids.name
FROM cl
LEFT JOIN o_t_ids  
ON cl.o_t_id = o_t_ids.id;


дает нужный результат.

хорошо, а что если еще условие есть, которые с запросом с JOIN не поставишь?

Дополню таблицу одним полем:

cl
---------------------
id | o_t_id | experation_time
---------------------

o_t_ids
---------------------
id | name
--------------------

т.е. появляется дополнительное условие: cl.experation_time is NULL.
Следующий запрос не работает:

SELECT cl.id, o_t_ids.name
FROM cl
LEFT JOIN o_t_ids  
ON cl.o_t_id = o_t_ids.id
AND cl.experation_time is NULL;
Akina
Дата: 25.01.2013 21:25:45
Viacheslav_mihalich
Следующий запрос не работает:

Работает. Только он не соответствует тому, что надо получить. Какого хрена второе условие залеплено в условие связывания?
SELECT cl.id, o_t_ids.name
FROM cl
LEFT JOIN o_t_ids  
ON cl.o_t_id = o_t_ids.id
WHERE cl.experation_time is NULL;
Viacheslav_mihalich
Дата: 26.01.2013 17:47:43
За подсказку спасибо!

запрос получился такой:

SELECT cl."ID", "O_T_IDS"."NAME", "P_T_IDS"."NAME", "D_IDS"."NAME",
FROM cl 
LEFT JOIN "O_T_IDS" ON "O_T_IDS"."ID" = cl."O_T_ID"
LEFT JOIN "P_T_IDS" ON "P_T_IDS"."ID" = cl."P_T_ID"
LEFT JOIN "D_IDS" ON "D_IDS"."ID" = cl."D_ID"
WHERE cl."S_ID" = 1
AND cl."EXPIRATION_TIME" is NULL 
order by cl."ID" asc;


результат получаем такой же как и с помощью запроса:

SELECT cl."ID", 
(SELECT "O_T_IDS"."NAME" FROM "O_T_IDS" WHERE "O_T_IDS"."ID" = cl."O_T_ID"),
(SELECT "P_T_IDS"."NAME" FROM "P_T_IDS" WHERE "P_T_IDS"."ID" = cl."P_T_ID"),
(SELECT "D_IDS"."NAME" FROM "D_IDS" WHERE "D_IDS"."ID" = cl."D_ID"),
FROM cl 
WHERE cl."S_ID" = 1
AND cl."EXPIRATION_TIME" is NULL 
order by cl."ID" asc;


для сравнения запустил выполнение обоих запросов в цикле на 10000 повторений.
Результат:

1-й запрос:
QUERY PLAN
Result  (cost=0.00..0.26 rows=1 width=0) (actual time=875.821..957.876 rows=50000 loops=1)
Total runtime: 1017.922 ms


2-й запрос:
QUERY PLAN
Result  (cost=0.00..0.26 rows=1 width=0) (actual time=752.993..834.105 rows=50000 loops=1)
Total runtime: 894.151 ms


чем же запрос с использованием LEFT JOIN лучше запроса с использованием подзапросов,
если первый медленнее выполняется?
tanglir
Дата: 26.01.2013 17:51:01
Viacheslav_mihalich,

это вопрос в форум по постгресу.