PostgreSQL 8.4 を使用しています。このクエリを最適化するのに最適なものは次のとおりです。
SELECT DISTINCT campaigns.* FROM campaigns
LEFT JOIN adverts ON campaign_id = campaigns.id
LEFT JOIN shops ON campaigns.shop_id = shops.id
LEFT JOIN exports_adverts ON advert_id = adverts.id
LEFT JOIN exports ON export_id = exports.id
LEFT JOIN rotations ON rotations.advert_id = adverts.id
LEFT JOIN blocks ON block_id = blocks.id
WHERE
(shops.is_active = TRUE)
AND exports.user_id = any(uids)
OR blocks.user_id = any(uids)
AND campaigns.id = any(ids)
私のテーブルは次のとおりです。
CREATE TABLE campaigns (
id integer NOT NULL,
shop_id integer NOT NULL,
title character varying NOT NULL,
...
);
CREATE TABLE adverts (
id integer NOT NULL,
campaign_id integer NOT NULL,
title character varying NOT NULL,
...
);
CREATE TABLE shops (
id integer NOT NULL,
title character varying NOT NULL,
is_active boolean DEFAULT true NOT NULL,
...
);
CREATE TABLE exports (
id integer NOT NULL,
title character varying,
user_id integer NOT NULL,
...
);
CREATE TABLE exports_adverts (
id integer NOT NULL,
export_id integer NOT NULL,
advert_id integer NOT NULL,
...
);
CREATE TABLE rotations (
id integer NOT NULL,
block_id integer NOT NULL,
advert_id integer NOT NULL,
...
);
CREATE TABLE blocks (
id integer NOT NULL,
title character varying NOT NULL,
user_id integer NOT NULL,
...
);
このクエリで使用されるすべてのフィールドのインデックスが既にあります。このクエリを最適化するためにできることはありますか?
このクエリの EXPLAIN:
Unique (cost=284529.95..321207.47 rows=57088 width=106) (actual time=508048.104..609870.600 rows=106 loops=1)
-> Sort (cost=284529.95..286567.59 rows=815056 width=106) (actual time=508048.102..602413.688 rows=8354563 loops=1)
Sort Key: campaigns.id, campaigns.shop_id, campaigns.title
Sort Method: external merge Disk: 1017136kB
-> Hash Left Join (cost=2258.33..62419.56 rows=815056 width=106) (actual time=49.509..17510.009 rows=8354563 loops=1)
Hash Cond: (rotations.block_id = blocks.id)
-> Merge Right Join (cost=1719.44..44560.73 rows=815056 width=110) (actual time=42.194..12317.422 rows=8354563 loops=1)
Merge Cond: (rotations.advert_id = adverts.id)
-> Index Scan using rotations_advert_id_key on rotations (cost=0.00..29088.30 rows=610999 width=8) (actual time=0.040..3026.898 rows=610999 loops=1)
-> Sort (cost=1719.44..1737.90 rows=7386 width=110) (actual time=42.144..3965.416 rows=8354563 loops=1)
Sort Key: adverts.id
Sort Method: external sort Disk: 1336kB
-> Hash Left Join (cost=739.01..1244.87 rows=7386 width=110) (actual time=10.519..21.351 rows=10571 loops=1)
Hash Cond: (exports_adverts.export_id = exports.id)
-> Hash Left Join (cost=715.60..1119.90 rows=7386 width=114) (actual time=10.178..17.472 rows=10571 loops=1)
Hash Cond: (adverts.id = exports_adverts.advert_id)
-> Hash Left Join (cost=304.71..433.53 rows=2781 width=110) (actual time=3.614..5.106 rows=3035 loops=1)
Hash Cond: (campaigns.id = adverts.campaign_id)
-> Hash Join (cost=1.13..9.32 rows=112 width=106) (actual time=0.051..0.303 rows=106 loops=1)
Hash Cond: (campaigns.shop_id = shops.id)
-> Seq Scan on campaigns (cost=0.00..6.23 rows=223 width=106) (actual time=0.011..0.150 rows=223 loops=1)
-> Hash (cost=1.08..1.08 rows=4 width=4) (actual time=0.015..0.015 rows=4 loops=1)
-> Seq Scan on shops (cost=0.00..1.08 rows=4 width=4) (actual time=0.010..0.012 rows=4 loops=1)
Filter: is_active
-> Hash (cost=234.37..234.37 rows=5537 width=8) (actual time=3.546..3.546 rows=5537 loops=1)
-> Seq Scan on adverts (cost=0.00..234.37 rows=5537 width=8) (actual time=0.010..2.200 rows=5537 loops=1)
-> Hash (cost=227.06..227.06 rows=14706 width=8) (actual time=6.532..6.532 rows=14706 loops=1)
-> Seq Scan on exports_adverts (cost=0.00..227.06 rows=14706 width=8) (actual time=0.016..3.028 rows=14706 loops=1)
-> Hash (cost=14.85..14.85 rows=685 width=4) (actual time=0.311..0.311 rows=685 loops=1)
-> Seq Scan on exports (cost=0.00..14.85 rows=685 width=4) (actual time=0.014..0.156 rows=685 loops=1)
-> Hash (cost=368.95..368.95 rows=13595 width=4) (actual time=7.281..7.281 rows=13595 loops=1)
-> Seq Scan on blocks (cost=0.00..368.95 rows=13595 width=4) (actual time=0.027..3.990 rows=13595 loops=1)