How to filter SQL results in a has-many-through relation

后端 未结 13 1653
有刺的猬
有刺的猬 2020-11-21 05:17

Assuming I have the tables student, club, and student_club:

student {
    id
    name
}
club {
    id
    name
}
stude         


        
13条回答
  •  孤城傲影
    2020-11-21 05:43

    Different query plans in query 2) and 10)

    I tested in a real life db, so the names differ from the catskin list. It's a backup copy, so nothing changed during all test runs (except minor changes to the catalogs).

    Query 2)

    SELECT a.*
    FROM   ef.adr a
    JOIN (
        SELECT adr_id
        FROM   ef.adratt
        WHERE  att_id IN (10,14)
        GROUP  BY adr_id
        HAVING COUNT(*) > 1) t using (adr_id);
    
    Merge Join  (cost=630.10..1248.78 rows=627 width=295) (actual time=13.025..34.726 rows=67 loops=1)
      Merge Cond: (a.adr_id = adratt.adr_id)
      ->  Index Scan using adr_pkey on adr a  (cost=0.00..523.39 rows=5767 width=295) (actual time=0.023..11.308 rows=5356 loops=1)
      ->  Sort  (cost=630.10..636.37 rows=627 width=4) (actual time=12.891..13.004 rows=67 loops=1)
            Sort Key: adratt.adr_id
            Sort Method:  quicksort  Memory: 28kB
            ->  HashAggregate  (cost=450.87..488.49 rows=627 width=4) (actual time=12.386..12.710 rows=67 loops=1)
                  Filter: (count(*) > 1)
                  ->  Bitmap Heap Scan on adratt  (cost=97.66..394.81 rows=2803 width=4) (actual time=0.245..5.958 rows=2811 loops=1)
                        Recheck Cond: (att_id = ANY ('{10,14}'::integer[]))
                        ->  Bitmap Index Scan on adratt_att_id_idx  (cost=0.00..94.86 rows=2803 width=0) (actual time=0.217..0.217 rows=2811 loops=1)
                              Index Cond: (att_id = ANY ('{10,14}'::integer[]))
    Total runtime: 34.928 ms
    

    Query 10)

    WITH two AS (
        SELECT adr_id
        FROM   ef.adratt
        WHERE  att_id IN (10,14)
        GROUP  BY adr_id
        HAVING COUNT(*) > 1
        )
    SELECT a.*
    FROM   ef.adr a
    JOIN   two using (adr_id);
    
    Hash Join  (cost=1161.52..1261.84 rows=627 width=295) (actual time=36.188..37.269 rows=67 loops=1)
      Hash Cond: (two.adr_id = a.adr_id)
      CTE two
        ->  HashAggregate  (cost=450.87..488.49 rows=627 width=4) (actual time=13.059..13.447 rows=67 loops=1)
              Filter: (count(*) > 1)
              ->  Bitmap Heap Scan on adratt  (cost=97.66..394.81 rows=2803 width=4) (actual time=0.252..6.252 rows=2811 loops=1)
                    Recheck Cond: (att_id = ANY ('{10,14}'::integer[]))
                    ->  Bitmap Index Scan on adratt_att_id_idx  (cost=0.00..94.86 rows=2803 width=0) (actual time=0.226..0.226 rows=2811 loops=1)
                          Index Cond: (att_id = ANY ('{10,14}'::integer[]))
      ->  CTE Scan on two  (cost=0.00..50.16 rows=627 width=4) (actual time=13.065..13.677 rows=67 loops=1)
      ->  Hash  (cost=384.68..384.68 rows=5767 width=295) (actual time=23.097..23.097 rows=5767 loops=1)
            Buckets: 1024  Batches: 1  Memory Usage: 1153kB
            ->  Seq Scan on adr a  (cost=0.00..384.68 rows=5767 width=295) (actual time=0.005..10.955 rows=5767 loops=1)
    Total runtime: 37.482 ms
    

提交回复
热议问题