0

フォーマットが混在していることを事前にお詫びします。見栄えを良くするために、少し分割しました。

私は通常、コストを使用してクエリの遅い部分を判断できますが、この場合は実際に広がっているように見え、あまり明白ではありません。何らかの理由で random() で並べ替えると、数ミリ秒から 8 秒に遅くなります。

EXPLAIN for:
  SELECT songs.*
  FROM "songs"
    INNER JOIN "posts" ON "posts"."id" = "songs"."post_id"
    INNER JOIN broadcasts on broadcasts.song_id = songs.id
    inner join stations as ss on ss.id = broadcasts.station_id
    inner join artists on artists.station_slug = ss.slug
    inner join artists_genres on artists_genres.artist_id = artists.id
    inner join genres on genres.id = artists_genres.genre_id
    inner join broadcasts bb on bb.song_id = songs.id
    inner join stations sss on sss.id = bb.station_id
    inner join blogs b on b.station_slug = sss.slug
    inner join blogs_genres on blogs_genres.blog_id = b.id
    inner join genres gg on gg.id = blogs_genres.genre_id
    INNER JOIN "stations" on "stations"."blog_id" = "songs"."blog_id"
    INNER JOIN blogs on blogs.id = posts.blog_id
  WHERE "songs"."working" = 't'
    AND "songs"."processed" = 't'
    AND (genres.id = 20 and gg.id = 20)
    AND (NOT EXISTS(
      SELECT NULL
      FROM authors
      WHERE authors.song_id = songs.id
      AND authors.role IN ('remixer', 'mashup')
    ))
    AND (songs.source != 'youtube')
    AND (songs.seconds < 600)
    AND (songs.matching_id = songs.id)
    ORDER BY random() desc
                                                                                                             QUERY PLAN
 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  Sort  (cost=3770.97..3770.98 rows=1 width=2132)
    Sort Key: (random())
    ->  Nested Loop  (cost=3142.28..3770.96 rows=1 width=2132)
          Join Filter: ((b.station_slug)::text = (sss.slug)::text)
          ->  Nested Loop Anti Join  (cost=3142.28..3762.68 rows=1 width=2150)
                ->  Nested Loop  (cost=2526.24..3135.35 rows=1 width=2150)
                      Join Filter: (posts.blog_id = blogs.id)
                      ->  Nested Loop  (cost=2526.24..3128.65 rows=1 width=2127)
                            ->  Nested Loop  (cost=2526.24..3127.39 rows=1 width=2131)
                                  ->  Hash Join  (cost=2515.19..3112.87 rows=1 width=2113)
                                        Hash Cond: (stations.blog_id = songs.blog_id)
                                        ->  Seq Scan on stations  (cost=0.00..475.49 rows=19549 width=40)
                                        ->  Hash  (cost=2515.15..2515.15 rows=3 width=2077)
                                              ->  Nested Loop  (cost=1265.66..2515.15 rows=3 width=2077)
                                                    ->  Nested Loop  (cost=1265.66..2506.44 rows=1 width=2077)
                                                          ->  Nested Loop  (cost=1265.66..2499.97 rows=1 width=1809)
                                                                ->  Nested Loop  (cost=1265.66..2498.71 rows=1 width=1813)
                                                                      ->  Hash Join  (cost=1265.66..2357.90 rows=277 width=8)
                                                                            Hash Cond: (broadcasts.station_id = ss.id)
                                                                            ->  Seq Scan on broadcasts  (cost=0.00..895.98 rows=51598 width=8)
                                                                            ->  Hash  (cost=1264.35..1264.35 rows=105 width=8)
                                                                                  ->  Hash Join  (cost=714.50..1264.35 rows=105 width=8)
                                                                                        Hash Cond: ((ss.slug)::text = (artists.station_slug)::text)
                                                                                        ->  Seq Scan on stations ss  (cost=0.00..475.49 rows=19549 width=18)
                                                                                        ->  Hash  (cost=713.20..713.20 rows=104 width=18)
                                                                                              ->  Nested Loop  (cost=5.06..713.20 rows=104 width=18)
                                                                                                    ->  Bitmap Heap Scan on artists_genres  (cost=5.06..99.85 rows=104 width=8)
                                                                                                          Recheck Cond: (genre_id = 20)
                                                                                                          ->  Bitmap Index Scan on index_artists_genres_on_genre_id_and_artist_id  (cost=0.00..5.03 rows=104 width=0)
                                                                                                                Index Cond: (genre_id = 20)
                                                                                                    ->  Index Scan using artists_pkey on artists  (cost=0.00..5.89 rows=1 width=18)
                                                                                                          Index Cond: (artists.id = artists_genres.artist_id)
                                                                      ->  Index Scan using index_songs_on_shared_id on songs  (cost=0.00..0.50 rows=1 width=1805)
                                                                            Index Cond: (songs.matching_id = broadcasts.song_id)
                                                                            Filter: (songs.working AND songs.processed AND ((songs.source)::text <> 'youtube'::text) AND (songs.seconds < 600) AND (songs.id = songs.matching_id))
                                                                ->  Seq Scan on genres  (cost=0.00..1.25 rows=1 width=4)
                                                                      Filter: (genres.id = 20)
                                                          ->  Index Scan using posts_pkey on posts  (cost=0.00..6.46 rows=1 width=268)
                                                                Index Cond: (posts.id = songs.post_id)
                                                    ->  Index Scan using index_songs_stations_on_song_id_and_station_id on broadcasts bb  (cost=0.00..8.67 rows=3 width=8)
                                                          Index Cond: (bb.song_id = broadcasts.song_id)
                                  ->  Hash Join  (cost=11.05..14.39 rows=13 width=18)
                                        Hash Cond: (blogs_genres.blog_id = b.id)
                                        ->  Bitmap Heap Scan on blogs_genres  (cost=4.35..7.51 rows=13 width=8)
                                              Recheck Cond: (genre_id = 20)
                                              ->  Bitmap Index Scan on index_blogs_genres_on_genre_id_and_blog_id  (cost=0.00..4.35 rows=13 width=0)
                                                    Index Cond: (genre_id = 20)
                                        ->  Hash  (cost=5.20..5.20 rows=120 width=18)
                                              ->  Seq Scan on blogs b  (cost=0.00..5.20 rows=120 width=18)
                            ->  Seq Scan on genres gg  (cost=0.00..1.25 rows=1 width=4)
                                  Filter: (gg.id = 20)
                      ->  Seq Scan on blogs  (cost=0.00..5.20 rows=120 width=31)
                ->  Bitmap Heap Scan on authors  (cost=616.04..623.56 rows=2 width=4)
                      Recheck Cond: (authors.song_id = songs.id)
                      Filter: ((authors.role)::text = ANY ('{remixer,mashup}'::text[]))
                      ->  Bitmap Index Scan on index_authors_on_artist_id_and_song_id_and_role  (cost=0.00..616.04 rows=2 width=0)
                            Index Cond: (authors.song_id = songs.id)
          ->  Index Scan using stations_pkey on stations sss  (cost=0.00..8.27 rows=1 width=18)
                Index Cond: (sss.id = bb.station_id)

減速の原因は何ですか?Mac で Postgres 9.1 を使用しています。

4

2 に答える 2

1

結合するすべての列のインデックスを作成したことを確認する必要があります。また、(私の経験から)ネストされたクエリを避けるようにしてください。そのため、 NOT EXISTS() セクションを書き直す必要がある場合があります。

于 2012-12-09T06:11:48.110 に答える