优化查询,PostgreSQL

时间:2016-09-08 13:11:28

标签: postgresql-9.4 explain

如何优化此查询? 我想查找firms2branchesproject_id中存在的firms accounts_premium之后的所有行。我的桌子:

-- 50000 rows
CREATE TABLE firms
(
  id bigserial NOT NULL,
  firm_id bigint NOT NULL,
  CONSTRAINT firms_pkey PRIMARY KEY (id)
)

-- 2 300 000 rows
CREATE TABLE firms2branches
(
  firm_id bigint NOT NULL,
  branch_id bigint NOT NULL,
  project_id bigint NOT NULL
)
CREATE INDEX firms2branches_firm_id_idx ON firms2branches USING btree(firm_id);

-- 6500 rows
CREATE TABLE accounts_premium
(
  firm_id bigint NOT NULL,
  is_active boolean NOT NULL DEFAULT false,
  CONSTRAINT accounts_premium_pkey PRIMARY KEY (firm_id)
)
CREATE INDEX accounts_premium_is_active_idx ON accounts_premium USING btree(is_active);

查询(使用冷缓存):

EXPLAIN (ANALYZE)
SELECT firms2branches.branch_id,
      firms2branches.firm_id
FROM firms2branches
JOIN firms ON firms.firm_id = firms2branches.firm_id
JOIN accounts_premium ON accounts_premium.firm_id = firms.id AND accounts_premium.is_active = TRUE
WHERE firms2branches.project_id = 21

结果(https://explain.depesz.com/s/oVNH):

Nested Loop  (cost=22.12..6958.10 rows=355 width=16) (actual time=151.123..417.764 rows=31 loops=1)
  Buffers: shared hit=7176 read=3371
  ->  Nested Loop  (cost=21.69..3100.40 rows=1435 width=8) (actual time=0.905..58.314 rows=1378 loops=1)
        Buffers: shared hit=3250 read=961
        ->  Bitmap Heap Scan on accounts_premium  (cost=21.40..226.90 rows=1435 width=8) (actual time=0.615..1.211 rows=1378 loops=1)
              Filter: is_active
              Heap Blocks: exact=61
              Buffers: shared hit=61 read=6
              ->  Bitmap Index Scan on accounts_premium_is_active_idx  (cost=0.00..21.04 rows=1435 width=0) (actual time=0.594..0.594 rows=1435 loops=1)
                    Index Cond: (is_active = true)
                    Buffers: shared read=6
        ->  Index Scan using firms_pkey on firms  (cost=0.29..1.90 rows=1 width=16) (actual time=0.040..0.041 rows=1 loops=1378)
              Index Cond: (id = accounts_premium.firm_id)
              Buffers: shared hit=3189 read=955
  ->  Index Scan using firms2branches_firm_id_idx on firms2branches  (cost=0.43..2.59 rows=1 width=16) (actual time=0.259..0.260 rows=0 loops=1378)
        Index Cond: (firm_id = firms.firm_id)
        Filter: (project_id = 21::bigint)
        Rows Removed by Filter: 2
        Buffers: shared hit=3926 read=2410
Planning time: 6.164 ms
Execution time: 417.843 ms

0 个答案:

没有答案