ORDER BY ... LIMIT and JOIN

Поиск
Список
Период
Сортировка
От Fizu
Тема ORDER BY ... LIMIT and JOIN
Дата
Msg-id 92cf04420908072302u7cec91f0se962665e771a5d03@mail.gmail.com
обсуждение исходный текст
Ответы Re: ORDER BY ... LIMIT and JOIN  (Michael Andreen <harv@ruin.nu>)
Список pgsql-performance
Hello,

I'm trying to optimize the follow query which returns the top users
ordered by ranking. I'll show you my schema and "explain analyze" for
each case.

So, i'm asking two things:

1) Why "ranking" index is not used in the second query when sorting.
2) Am i missing some obvious optimization like a missing index? :)

Schemas:

# \d ranking
            Table "public.ranking"
  Column   |         Type          | Modifiers
-----------+-----------------------+-----------
 ranking   | bigint                |
 score     | double precision      |
 username  | character varying(20) | not null
 variation | bigint                |
Indexes:
    "ranking_tmp_pkey1" PRIMARY KEY, btree (username)
    "idxrank_6057" btree (ranking) CLUSTER


# \d user
                                  Table "public.user"
   Column   |         Type          |                     Modifiers
------------+-----------------------+---------------------------------------------------
 id         | integer               | not null default
nextval('user_id_seq'::regclass)
 username   | character varying(20) | not null
 about      | text                  |
 name       | character varying(50) |
 photo      | text                  |
 country_id | integer               |
Indexes:
    "user_pkey" PRIMARY KEY, btree (username)
    "country_ranking_user_idx" btree (country_id)


Explain:

#  explain analyze SELECT * FROM "ranking" INNER JOIN "user" ON
("ranking"."username" = "user"."username") WHERE "user"."country_id" =
1  ORDER BY "ranking"."ranking" ASC LIMIT 100;

 QUERY PLAN

----------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=13.03..13.04 rows=1 width=180) (actual
time=965.229..965.302 rows=100 loops=1)
   ->  Sort  (cost=13.03..13.04 rows=1 width=180) (actual
time=965.227..965.256 rows=100 loops=1)
         Sort Key: ranking.ranking
         Sort Method:  top-N heapsort  Memory: 56kB
         ->  Nested Loop  (cost=0.00..13.02 rows=1 width=180) (actual
time=0.049..900.847 rows=57309 loops=1)
               ->  Index Scan using country_ranking_user_idx on "user"
 (cost=0.00..6.49 rows=1 width=145) (actual time=0.023..57.633
rows=57309 loops=1)
                     Index Cond: (country_id = 1)
               ->  Index Scan using ranking_tmp_pkey1 on ranking
(cost=0.00..6.52 rows=1 width=35) (actual time=0.013..0.013 rows=1
loops=57309)
                     Index Cond: ((ranking.username)::text =
("user".username)::text)
 Total runtime: 965.412 ms
(10 rows)

# explain analyze SELECT * FROM "ranking" INNER JOIN "user" ON
("ranking"."username" = "user"."username") ORDER BY
"ranking"."ranking" ASC LIMIT 100;

QUERY PLAN

-----------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..137.02 rows=100 width=180) (actual
time=0.056..1.973 rows=100 loops=1)
   ->  Nested Loop  (cost=0.00..3081316.65 rows=2248753 width=180)
(actual time=0.055..1.921 rows=100 loops=1)
         ->  Index Scan using idxrank_6057 on ranking
(cost=0.00..70735.73 rows=2248753 width=35) (actual time=0.021..0.076
rows=100 loops=1)
         ->  Index Scan using user_pkey on "user"  (cost=0.00..1.33
rows=1 width=145) (actual time=0.016..0.017 rows=1 loops=100)
               Index Cond: (("user".username)::text = (ranking.username)::text)
 Total runtime: 2.043 ms
(6 rows)


Thanks!
Fz

В списке pgsql-performance по дате отправления:

Предыдущее
От: Bruce Momjian
Дата:
Сообщение: Re: [BUGS] BUG #4919: CREATE USER command slows down system performance
Следующее
От: Pierre Frédéric Caillaud
Дата:
Сообщение: Re: PG-related ACM Article: "The Pathologies of Big Data"