Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Как по плану выбрать запрос? / 12 сообщений из 12, страница 1 из 1
14.05.2014, 18:18:35
    #38641414
учздфшт
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как по плану выбрать запрос?
Здравствуйте,

Как понять какой из двух запросов быстрее?

Код: sql
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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
> explain SELECT "movie"."id" FROM "movie"
                       WHERE "movie"."mal_id" IS NULL AND NOT EXISTS
                                    (SELECT "movie_genres"."movie_id" FROM "movie_genres" INNER JOIN "genres" ON "genres"."id" =  "movie_genres"."genre_id" AND "genres"."name" = 'Influenced' AND "movie_genres"."movie_id"="movie"."id");
                                                   QUERY PLAN
-----------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on movie  (cost=5.06..2242.83 rows=50 width=4)
   Recheck Cond: (mal_id IS NULL)
   Filter: (NOT (SubPlan 1))
   ->  Bitmap Index Scan on index_movie_on_mal_id  (cost=0.00..5.04 rows=101 width=0)
         Index Cond: (mal_id IS NULL)
   SubPlan 1
     ->  Nested Loop  (cost=0.29..19.40 rows=1 width=0)
           Join Filter: (movie_genres.genre_id = genres.id)
           ->  Seq Scan on genres  (cost=0.00..10.88 rows=1 width=4)
                 Filter: ((name)::text = 'Influenced'::text)
           ->  Index Scan using index_movie_genres_on_movie_id on movie_genres  (cost=0.29..8.49 rows=3 width=4)
                 Index Cond: (movie_id = movie.id)
(12 rows)

Time: 40.623 ms
> explain SELECT "movie"."id" FROM "movie"
                        WHERE "movie"."mal_id" IS NULL AND "movie"."id" NOT IN
                                 (SELECT "movie_genres"."movie_id" FROM "movie_genres" INNER JOIN "genres" ON "genres"."id" =  "movie_genres"."genre_id" AND "genres"."name" = 'Influenced');
                                                  QUERY PLAN
--------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on movie  (cost=153.85..432.30 rows=50 width=4)
   Recheck Cond: (mal_id IS NULL)
   Filter: (NOT (hashed SubPlan 1))
   ->  Bitmap Index Scan on index_movie_on_mal_id  (cost=0.00..5.04 rows=101 width=0)
         Index Cond: (mal_id IS NULL)
   SubPlan 1
     ->  Nested Loop  (cost=16.58..147.92 rows=349 width=4)
           ->  Seq Scan on genres  (cost=0.00..10.88 rows=1 width=4)
                 Filter: ((name)::text = 'Influenced'::text)
           ->  Bitmap Heap Scan on movie_genres  (cost=16.58..131.51 rows=554 width=8)
                 Recheck Cond: (genre_id = genres.id)
                 ->  Bitmap Index Scan on index_movie_genres_on_genre_id  (cost=0.00..16.44 rows=554 width=0)
                       Index Cond: (genre_id = genres.id)
(13 rows)

Time: 19.340 ms
...
Рейтинг: 0 / 0
14.05.2014, 19:18:18
    #38641467
Ёш
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как по плану выбрать запрос?
учздфштКак понять какой из двух запросов быстрее?
Выполните оба и узнаете какой быстрее.
...
Рейтинг: 0 / 0
14.05.2014, 19:26:03
    #38641472
daevy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как по плану выбрать запрос?
учздфшт,

выполните оба и включите \timing перед выполнением
...
Рейтинг: 0 / 0
14.05.2014, 19:42:38
    #38641482
Oleg Bartunov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как по плану выбрать запрос?
учздфшт,

explain analyze
...
Рейтинг: 0 / 0
14.05.2014, 21:52:11
    #38641547
учздфшт
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как по плану выбрать запрос?
Oleg Bartunov,

Код: sql
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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
>

> explain analyze SELECT "movie"."id" FROM "movie"
                                  WHERE "movie"."mal_id" IS NULL AND
                                  NOT EXISTS (SELECT "movie_genres"."movie_id" FROM "movie_genres" INNER JOIN "genres" ON "genres"."id" =  "movie_genres"."genre_id" AND "genres"."name" = 'Influenced' AND "movie_genres"."movie_id"="movie"."id");
                                                                         QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on movie  (cost=5.06..2242.90 rows=50 width=4) (actual time=3.194..26.580 rows=61 loops=1)
   Recheck Cond: (mal_id IS NULL)
   Filter: (NOT (SubPlan 1))
   Rows Removed by Filter: 39
   ->  Bitmap Index Scan on index_movie_on_mal_id  (cost=0.00..5.04 rows=101 width=0) (actual time=0.462..0.462 rows=103 loops=1)
         Index Cond: (mal_id IS NULL)
   SubPlan 1
     ->  Nested Loop  (cost=0.29..19.40 rows=1 width=0) (actual time=0.213..0.213 rows=0 loops=100)
           Join Filter: (movie_genres.genre_id = genres.id)
           Rows Removed by Join Filter: 2
           ->  Seq Scan on genres  (cost=0.00..10.88 rows=1 width=4) (actual time=0.085..0.092 rows=1 loops=100)
                 Filter: ((name)::text = 'Influenced'::text)
                 Rows Removed by Filter: 43
           ->  Index Scan using index_movie_genres_on_movie_id on movie_genres  (cost=0.29..8.49 rows=3 width=4) (actual time=0.031..0.051 rows=3 loops=100)
                 Index Cond: (movie_id = movie.id)
 Total runtime: 27.773 ms
(16 rows)

Time: 36.717 ms
> explain analyze SELECT "movie"."id" FROM "movie"
                                    WHERE "movie"."mal_id" IS NULL AND
                                    "movie"."id" NOT IN (SELECT "movie_genres"."movie_id" FROM "movie_genres" INNER JOIN "genres" ON "genres"."id" =  "movie_genres"."genre_id" AND "genres"."name" = 'Influenced');
                                                                       QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on movie  (cost=153.85..432.37 rows=50 width=4) (actual time=2.990..4.340 rows=61 loops=1)
   Recheck Cond: (mal_id IS NULL)
   Filter: (NOT (hashed SubPlan 1))
   Rows Removed by Filter: 39
   ->  Bitmap Index Scan on index_movie_on_mal_id  (cost=0.00..5.04 rows=101 width=0) (actual time=0.271..0.271 rows=103 loops=1)
         Index Cond: (mal_id IS NULL)
   SubPlan 1
     ->  Nested Loop  (cost=16.58..147.92 rows=349 width=4) (actual time=0.298..1.339 rows=39 loops=1)
           ->  Seq Scan on genres  (cost=0.00..10.88 rows=1 width=4) (actual time=0.038..0.041 rows=1 loops=1)
                 Filter: ((name)::text = 'Influenced'::text)
                 Rows Removed by Filter: 43
           ->  Bitmap Heap Scan on movie_genres  (cost=16.58..131.51 rows=554 width=8) (actual time=0.248..0.732 rows=39 loops=1)
                 Recheck Cond: (genre_id = genres.id)
                 ->  Bitmap Index Scan on index_movie_genres_on_genre_id  (cost=0.00..16.44 rows=554 width=0) (actual time=0.227..0.227 rows=39 loops=1)
                       Index Cond: (genre_id = genres.id)
 Total runtime: 5.770 ms
(16 rows)
...
Рейтинг: 0 / 0
15.05.2014, 06:21:42
    #38641691
daevy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как по плану выбрать запрос?
учздфшт,

вот первый запросы выполняется за ~27ms, второй за ~5ms, собственно второй и быстрее.

но вот любопытно почему "Bitmap Heap Scan on movie" в первом варианте работает медленнее чем во втором... хотя в запросе используется более предпочитаемый NOT EXISTS.
...
Рейтинг: 0 / 0
15.05.2014, 11:10:01
    #38641936
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как по плану выбрать запрос?
И надо учитывать что:

у вас там всего по сотне записей на таблицу...
если оно так и будет в дальнейшем - тогда да выбирать то что быстрее по explain analyze

если же ожидается что будет в 10-100-1000 и более раз больше записей хоть в одной из участвующих таблиц - тестировать и сравнивать надо на ожидаемых обьемах.
Так как тот запрос который был оптимальным на 100 записях вполне может оказаться крайне неоптимальным на 100.000 записей...
...
Рейтинг: 0 / 0
15.05.2014, 16:36:30
    #38642513
Ivan Durak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как по плану выбрать запрос?
daevyучздфшт,

вот первый запросы выполняется за ~27ms, второй за ~5ms, собственно второй и быстрее.

но вот любопытно почему "Bitmap Heap Scan on movie" в первом варианте работает медленнее чем во втором... хотя в запросе используется более предпочитаемый NOT EXISTS.
нот экзист 100 раз сканит подзапрос. нот ин - 1 раз. Почуствуйте разницу
...
Рейтинг: 0 / 0
15.05.2014, 19:47:13
    #38642738
daevy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как по плану выбрать запрос?
Ivan Durakнот экзист 100 раз сканит подзапрос. нот ин - 1 раз. Почуствуйте разницу
как я понял в explain analyze это не видно... скиньте пруф, интересно почитать.
...
Рейтинг: 0 / 0
16.05.2014, 11:44:44
    #38643241
Ivan Durak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как по плану выбрать запрос?
daevyIvan Durakнот экзист 100 раз сканит подзапрос. нот ин - 1 раз. Почуствуйте разницу
как я понял в explain analyze это не видно... скиньте пруф, интересно почитать.
все видно:
loops=1
loops=100
Nested Loop (cost=0.29..19.40 rows=1 width=0) (actual time=0.213..0.213 rows=0 loops=100 )
Nested Loop (cost=16.58..147.92 rows=349 width=4) (actual time=0.298..1.339 rows=39 loops=1 )
...
Рейтинг: 0 / 0
16.05.2014, 11:46:12
    #38643245
Ivan Durak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как по плану выбрать запрос?
Да это и так очевидно.
В
NOT EXISTS
подзапрос КОРРЕЛИРОВАННЫЙ
(есть "movie_genres"."movie_id"="movie"."id")
а в NOT IN
не коррелированный и его достаточно один раз прогнать
...
Рейтинг: 0 / 0
16.05.2014, 12:05:55
    #38643272
daevy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как по плану выбрать запрос?
Ivan Durak,

во, спасибо
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Как по плану выбрать запрос? / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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