3

多対多の関係に参加することに関してさらに質問がありますが、新しい質問をする方がよいと思いました。

完全なクエリ:

SELECT p.id
     ,(100 * sum((a.price > 0)::int)) / cc.ct AS commercial
     ,(100 * sum((a.price = 0)::int)) / cf.ct AS free
FROM  (SELECT count(*)::float AS ct FROM applications WHERE price > 0) AS cc
     ,(SELECT count(*)::float AS ct FROM applications WHERE price = 0) AS cf
     ,permissions p
LEFT   JOIN applications_permissions ap ON ap.permission_id = p.id
LEFT   JOIN applications a ON a.id = ap.application_id
GROUP  BY 1, cc.ct, cf.ct
ORDER  BY 2 DESC, 3 DESC, 1;

実行時間について:

SELECT p.id

-> 合計実行時間: 2,467.801 ミリ秒

SELECT (SELECT regex FROM permissions WHERE id = p.id) AS regex

-> 合計実行時間: 28,882.293 ミリ秒

ここで何が起きてるの?これを行う正しい方法は何ですか?

p.id を選択

QUERY PLAN
Sort  (cost=123257.63..123258.07 rows=178 width=24)
  Sort Key: (((sum(((a.price > 0::double precision))::integer))::double precision / ((count(*))::double precision))), (((sum(((a.price = 0::double precision))::integer))::double precision / ((count(*))::double precision))), p.id
  ->  HashAggregate  (cost=123244.74..123250.97 rows=178 width=24)
        ->  Hash Left Join  (cost=53709.64..115103.31 rows=651315 width=24)
              Hash Cond: (ap.application_id = a.id)
              ->  Hash Left Join  (cost=42222.11..82232.48 rows=651315 width=24)
                    Hash Cond: (p.id = ap.permission_id)
                    ->  Nested Loop  (cost=18283.65..18305.06 rows=178 width=20)
                          ->  Index Scan using permissions_pkey on permissions p  (cost=0.00..17.85 rows=178 width=4)
                                Filter: (regex IS NOT NULL)
                          ->  Materialize  (cost=18283.65..18283.66 rows=1 width=16)
                                ->  Nested Loop  (cost=18283.60..18283.65 rows=1 width=16)
                                      ->  Aggregate  (cost=9016.51..9016.52 rows=1 width=0)
                                            ->  Seq Scan on applications  (cost=0.00..8915.85 rows=40262 width=0)
                                                  Filter: (price > 0::double precision)
                                      ->  Aggregate  (cost=9267.09..9267.10 rows=1 width=0)
                                            ->  Seq Scan on applications  (cost=0.00..8915.85 rows=140494 width=0)
                                                  Filter: (price = 0::double precision)
                    ->  Hash  (cost=11271.65..11271.65 rows=772065 width=8)
                          ->  Seq Scan on applications_permissions ap  (cost=0.00..11271.65 rows=772065 width=8)
              ->  Hash  (cost=8453.68..8453.68 rows=184868 width=8)
                    ->  Seq Scan on applications a  (cost=0.00..8453.68 rows=184868 width=8)
22 row(s)
Total runtime: 4.524 ms

選択 (選択 ...)

QUERY PLAN
Sort  (cost=3796049.42..3796049.86 rows=178 width=24)
  Sort Key: (((sum(((a.price > 0::double precision))::integer))::double precision / ((count(*))::double precision))), (((sum(((a.price = 0::double precision))::integer))::double precision / ((count(*))::double precision))), ((SubPlan 1))
  ->  HashAggregate  (cost=3795033.06..3796042.76 rows=178 width=24)
        ->  Hash Left Join  (cost=53709.64..3786891.62 rows=651315 width=24)
              Hash Cond: (ap.application_id = a.id)
              ->  Hash Left Join  (cost=42222.11..82232.48 rows=651315 width=24)
                    Hash Cond: (p.id = ap.permission_id)
                    ->  Nested Loop  (cost=18283.65..18305.06 rows=178 width=20)
                          ->  Index Scan using permissions_pkey on permissions p  (cost=0.00..17.85 rows=178 width=4)
                                Filter: (regex IS NOT NULL)
                          ->  Materialize  (cost=18283.65..18283.66 rows=1 width=16)
                                ->  Nested Loop  (cost=18283.60..18283.65 rows=1 width=16)
                                      ->  Aggregate  (cost=9016.51..9016.52 rows=1 width=0)
                                            ->  Seq Scan on applications  (cost=0.00..8915.85 rows=40262 width=0)
                                                  Filter: (price > 0::double precision)
                                      ->  Aggregate  (cost=9267.09..9267.10 rows=1 width=0)
                                            ->  Seq Scan on applications  (cost=0.00..8915.85 rows=140494 width=0)
                                                  Filter: (price = 0::double precision)
                    ->  Hash  (cost=11271.65..11271.65 rows=772065 width=8)
                          ->  Seq Scan on applications_permissions ap  (cost=0.00..11271.65 rows=772065 width=8)
              ->  Hash  (cost=8453.68..8453.68 rows=184868 width=8)
                    ->  Seq Scan on applications a  (cost=0.00..8453.68 rows=184868 width=8)
              SubPlan 1
                ->  Seq Scan on permissions  (cost=0.00..5.64 rows=1 width=26)
                      Filter: (id = $0)
25 row(s)
Total runtime: 6.566 ms
4

1 に答える 1

1

SELECT列を選択するだけで、相関サブクエリをリストに追加しようとしているようです。

SELECT p.id, p.regex
     ,(100 * sum((a.price > 0)::int)) / cc.ct AS commercial
     ,(100 * sum((a.price = 0)::int)) / cf.ct AS free
FROM  (SELECT count(*)::float AS ct FROM applications WHERE price > 0) AS cc
     ,(SELECT count(*)::float AS ct FROM applications WHERE price = 0) AS cf
     ,permissions p
LEFT   JOIN applications_permissions ap ON ap.permission_id = p.id
LEFT   JOIN applications a ON a.id = ap.application_id
GROUP  BY p.id, p.regex, cc.ct, cf.ct
ORDER  BY commercial DESC, free DESC, p.id;

が主キーの場合、テーブル全体をカバーし、Postgres 9.1 以降追加するp.id必要はありません。p.regexGROUP BY

于 2012-07-02T19:09:26.423 に答える