Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Эффективность подзапросов? / 14 сообщений из 14, страница 1 из 1
28.06.2007, 17:00
    #34626794
uniqus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эффективность подзапросов?
Товарищи, вопрос пожалуй задавался уже неоднократно, но найти ответа я не могу: насколько эффективны подзапросы в PostgreSQL? Например, есть такой запрос:

SELECT * FROM t1 WHERE id1 IN (SELECT id1 FROM t2 WHERE id2 IN (SELECT id3 FROM t3)));

Вложенные подзапросы будут выполняться для каждой строки в таблице t1 (а последний еще и для каждой строки в таблице t2)? Или же они выполнятся однократно, и потом для каждой строки будут использоваться одни и те же результаты?

И вообще, что эффективней использовать: подзапросы или JOIN'ы?

Заранее спасибо.
...
Рейтинг: 0 / 0
28.06.2007, 18:11
    #34627090
angro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эффективность подзапросов?
надо смотреть план выполнения
...
Рейтинг: 0 / 0
28.06.2007, 18:45
    #34627171
assa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эффективность подзапросов?
uniqusВложенные подзапросы будут выполняться для каждой строки в таблице t1 (а последний еще и для каждой строки в таблице t2)? Или же они выполнятся однократно, и потом для каждой строки будут использоваться одни и те же результаты?

И вообще, что эффективней использовать: подзапросы или JOIN'ы?
1. по моему - для каждой. (можно помудрить на тему замену позапросов STABLE функциями. по крайней мере по описанию смысла модификатора STABLE - должно выполняться один раз на стейтмент).

2. JOIN-ы видимо предпочтительнее. Но бывают особости. В том числе - особенности оптимизаторов.
...
Рейтинг: 0 / 0
28.06.2007, 19:33
    #34627232
uniqus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эффективность подзапросов?
angroнадо смотреть план выполнения
Я не совсем разбираюсь в этом, точнее сказать, совсем не разбираюсь =D
Но вот что я получил эксплейном:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
pharm=# EXPLAIN SELECT * FROM ph_boxes WHERE box_id IN (SELECT box_id FROM ph_affiliate_store WHERE store_id= 3 );
                                  QUERY PLAN
------------------------------------------------------------------------------
 Hash IN Join  (cost= 1 . 05 .. 2 . 10  rows= 1  width= 213 )
   Hash Cond: (ph_boxes.box_id = ph_affiliate_store.box_id)
   ->  Seq Scan on ph_boxes  (cost= 0 . 00 .. 1 . 03  rows= 3  width= 213 )
   ->  Hash  (cost= 1 . 04 .. 1 . 04  rows= 1  width= 8 )
         ->  Seq Scan on ph_affiliate_store  (cost= 0 . 00 .. 1 . 04  rows= 1  width= 8 )
               Filter: (store_id =  3 )
( 6  rows)

pharm=# EXPLAIN SELECT DISTINCT ON (box_id) b.* FROM ph_affiliate_store AS s LEFT JOIN ph_boxes AS b USING (box_id) WHERE store_id
                                      QUERY PLAN
--------------------------------------------------------------------------------------
 Unique  (cost= 2 . 11 .. 2 . 12  rows= 1  width= 213 )
   ->  Sort  (cost= 2 . 11 .. 2 . 12  rows= 1  width= 213 )
         Sort Key: b.box_id
         ->  Nested Loop Left Join  (cost= 0 . 00 .. 2 . 11  rows= 1  width= 213 )
               Join Filter: (s.box_id = b.box_id)
               ->  Seq Scan on ph_affiliate_store s  (cost= 0 . 00 .. 1 . 04  rows= 1  width= 8 )
                     Filter: (store_id =  3 )
               ->  Seq Scan on ph_boxes b  (cost= 0 . 00 .. 1 . 03  rows= 3  width= 213 )
( 8  rows)

pharm=# EXPLAIN SELECT b.* FROM ph_affiliate_store AS s LEFT JOIN ph_boxes AS b USING (box_id) WHERE store_id =  3 ;
                                QUERY PLAN
--------------------------------------------------------------------------
 Nested Loop Left Join  (cost= 0 . 00 .. 2 . 11  rows= 1  width= 213 )
   Join Filter: (s.box_id = b.box_id)
   ->  Seq Scan on ph_affiliate_store s  (cost= 0 . 00 .. 1 . 04  rows= 1  width= 8 )
         Filter: (store_id =  3 )
   ->  Seq Scan on ph_boxes b  (cost= 0 . 00 .. 1 . 03  rows= 3  width= 213 )
( 5  rows)
Кто-то скажет мне, как это всё трактовать? Интуитивно догадываюсь, что как-то по "cost", но хотелось бы уточнить... Или план выполнения совсем не эксплейном нужно получать?
...
Рейтинг: 0 / 0
28.06.2007, 19:36
    #34627235
uniqus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эффективность подзапросов?
Или вот еще один вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
pharm=# explain select b.* FROM ph_boxes AS b LEFT JOIN ph_affiliate_store AS s USING (box_id) WHERE store_id IS NOT NULL;
                                   QUERY PLAN
--------------------------------------------------------------------------------
 Hash Join  (cost= 1 . 07 .. 2 . 14  rows= 3  width= 213 )
   Hash Cond: (b.box_id = s.box_id)
   ->  Seq Scan on ph_boxes b  (cost= 0 . 00 .. 1 . 03  rows= 3  width= 213 )
   ->  Hash  (cost= 1 . 03 .. 1 . 03  rows= 3  width= 8 )
         ->  Seq Scan on ph_affiliate_store s  (cost= 0 . 00 .. 1 . 03  rows= 3  width= 8 )
               Filter: (store_id IS NOT NULL)
( 6  rows)
...
Рейтинг: 0 / 0
28.06.2007, 19:39
    #34627242
uniqus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эффективность подзапросов?
assa1. по моему - для каждой. (можно помудрить на тему замену позапросов STABLE функциями. по крайней мере по описанию смысла модификатора STABLE - должно выполняться один раз на стейтмент).

2. JOIN-ы видимо предпочтительнее. Но бывают особости. В том числе - особенности оптимизаторов.
Спасибо, посмотрю, что дас STABLE. Только там еще есть модификатор IMMUTABLE, я так и не понял, какой же все-таки что из них делает, и как они различаются. По всей видимости, надо прокачивать скилл "знание английского" :)
...
Рейтинг: 0 / 0
28.06.2007, 20:37
    #34627298
tkopets
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эффективность подзапросов?
У тебя очень мало строк в этих таблицах, при большем количестве строк план выполнения запроса может кардинально поменяться. Я б рекомендовал проводить тест с минимум в 1000 строк в каждой таблице. Или я ошибаюсь, і в тех таблицах так и будет постоянно 1-3 записи? Тогда можно абсолютно не беспокоиться о производительности запросов, которые обрабатывают 3-5 строк.
_____________________________________
Sorry for my Russian, if it is not OK
...
Рейтинг: 0 / 0
29.06.2007, 00:09
    #34627496
uniqus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эффективность подзапросов?
tkopetsИли я ошибаюсь, і в тех таблицах так и будет постоянно 1-3 записи?
Нет, строк действительно будет порядка 800-1000. Наверное, таки попробую заполнить таблицы и погонять все три запроса. Спасибо за ответ :)
...
Рейтинг: 0 / 0
29.06.2007, 00:19
    #34627509
Thamerlan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эффективность подзапросов?
uniqus tkopetsИли я ошибаюсь, і в тех таблицах так и будет постоянно 1-3 записи?
Нет, строк действительно будет порядка 800-1000. Наверное, таки попробую заполнить таблицы и погонять все три запроса. Спасибо за ответ :)


1000 строк :) Ну это несколько 8kb блоков... Я бы даже не заморачивался с оптимизацией.
...
Рейтинг: 0 / 0
29.06.2007, 00:43
    #34627522
uniqus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эффективность подзапросов?
Thamerlan[quot uniqus][quot tkopets]1000 строк :) Ну это несколько 8kb блоков... Я бы даже не заморачивался с оптимизацией.
Ну, это вопрос скорее концептуального характера. Сейчас 1000, а завтра може будет и таблица с 1000000, и как я в таком случае должен буду поступать? :)
...
Рейтинг: 0 / 0
29.06.2007, 15:15
    #34629107
tkopets
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эффективность подзапросов?
На таблице в 3-10 записей PostgreSQL никогда не виберет Index Scan, на таких микроскопических таблицах он всегда будет исполбзовать Seq Scan, что и видно с твоих EXLAIN'ов.
_____________________________________
Sorry for my Russian, if it is not OK
...
Рейтинг: 0 / 0
29.06.2007, 15:21
    #34629131
MBG
MBG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эффективность подзапросов?
Если в таблице меньше 100 тысяч записей, оптимизация обычно бесполезна - если делается выборка, то она делается относительно быстро (если индексы правильно созданы и не замусорены), а если обрабатываются все записи таблицы, то это происходит относительно медленно (пора создавать кэш-таблицы или материализованные виды, на ваш вкус).
...
Рейтинг: 0 / 0
05.08.2007, 19:37
    #34706415
Mayc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эффективность подзапросов?
MBG (пора создавать кэш-таблицы или материализованные виды, на ваш вкус).
Вроде ж, Postgres не поддерживает MATERIALIZED VIEW. Есть только эмуляция на костылях PL/PgSql.
...
Рейтинг: 0 / 0
07.08.2007, 01:36
    #34709202
iz
iz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эффективность подзапросов?
когда планнер видит, что подзапрос возвращает большое количество рядов, он сам "выпрямляет" запрос, переводя его на более эффективный джойн. так что не бойтесь за рост таблицы, но не забывайте регулярно обновлять статистику (analyze).
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Эффективность подзапросов? / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]