如何使用JOIN许多值优化SQL查询?

时间:2019-07-01 08:56:27

标签: sql postgresql query-optimization

我有一个这样的查询,其中联接〜6000个值:

SELECT MAX(user_id) as user_id, SUM(sum_amount_win) as sum_amount_win 
FROM (
  SELECT    
      a1.user_id
      ,CASE When MAX(currency) = 'RUB' Then SUM(d1.amount_cents)  END as sum_amount_win                        
  FROM dense_balance_transactions as d1
    JOIN accounts a1 ON a1.id = d1.account_id
    JOIN (
      VALUES (5),(22),(26) -- ~6000 values 
    ) AS v(user_id) USING (user_id)
  WHERE d1.created_at BETWEEN '2019-06-01 00:00:00' AND '2019-06-20 23:59:59' 
      AND d1.action='win'
  GROUP BY a1.user_id, a1.currency
) as t 
GROUP BY user_id

用于查询具有许多值的查询计划:

GroupAggregate  (cost=266816.48..266816.54 rows=1 width=48) (actual time=5024.201..5102.633 rows=5745 loops=1)
  Group Key: a1.user_id
  Buffers: shared hit=12205927
  ->  GroupAggregate  (cost=266816.48..266816.51 rows=1 width=44) (actual time=5024.185..5099.621 rows=5774 loops=1)
        Group Key: a1.user_id, a1.currency
        Buffers: shared hit=12205927
        ->  Sort  (cost=266816.48..266816.49 rows=1 width=20) (actual time=5024.170..5041.840 rows=291122 loops=1)
              Sort Key: a1.user_id, a1.currency
              Sort Method: quicksort  Memory: 35032kB
              Buffers: shared hit=12205927
              ->  Gather  (cost=214410.62..266816.47 rows=1 width=20) (actual time=292.828..5204.320 rows=291122 loops=1)
                    Workers Planned: 5
                    Workers Launched: 5
                    Buffers: shared hit=12205921
                    ->  Nested Loop  (cost=213410.62..265816.37 rows=1 width=20) (actual time=255.028..3939.300 rows=48520 loops=6)
                          Buffers: shared hit=12205921
                          ->  Merge Join  (cost=213410.19..214522.45 rows=1269 width=20) (actual time=253.545..274.872 rows=1136 loops=6)
                                Merge Cond: (a1.user_id = "*VALUES*".column1)
                                Buffers: shared hit=191958
                                ->  Sort  (cost=212958.66..213493.45 rows=213914 width=20) (actual time=251.991..263.828 rows=82468 loops=6)
                                      Sort Key: a1.user_id
                                      Sort Method: quicksort  Memory: 24322kB
                                      Buffers: shared hit=191916
                                      ->  Parallel Seq Scan on accounts a1  (cost=0.00..194020.14 rows=213914 width=20) (actual time=0.042..196.052 rows=179242 loops=6)
                                            Buffers: shared hit=191881
                                ->  Sort  (cost=451.52..466.52 rows=6000 width=4) (actual time=1.547..2.429 rows=6037 loops=6)
                                      Sort Key: "*VALUES*".column1
                                      Sort Method: quicksort  Memory: 474kB
                                      Buffers: shared hit=42
                                      ->  Values Scan on "*VALUES*"  (cost=0.00..75.00 rows=6000 width=4) (actual time=0.002..0.928 rows=6000 loops=6)
                          ->  Index Scan using index_dense_balance_transactions_on_account_id on dense_balance_transactions d1  (cost=0.44..40.41 rows=1 width=16) (actual time=0.160..3.220 rows=43 loops=6816)
                                Index Cond: (account_id = a1.id)
                                Filter: ((created_at >= '2019-06-01 00:00:00'::timestamp without time zone) AND (created_at <= '2019-06-20 23:59:59'::timestamp without time zone) AND ((action)::text = 'win'::text))
                                Rows Removed by Filter: 1942
                                Buffers: shared hit=12013963
Planning time: 10.239 ms
Execution time: 5387.523 ms

我使用PosgreSQL 10.8.0。 有没有机会加快此查询的速度?

0 个答案:

没有答案