我有一个查询,它需要太长时间才能运行。 我正在使用PostgreSQL 10.3。 在我参与此查询的表中,每个记录中有大约350万条记录。 查询是:
SELECT thf.attr1, thf.attr2, thf.attr3, thf.attr4
FROM tb_one AS thf
INNER JOIN tb_two AS ths
ON ths.tb_hit_hitid = thf.tb_hit_hitid
WHERE ths.source IN ('source1', 'source2')
在这些表中,我有索引:
CREATE INDEX tb_two_idx_1 on tb_two (Source ASC, attr5 ASC);
CREATE INDEX tb_one_idx_1 on tb_one USING btree (attr1 ASC,attr2 ASC,attr3 ASC,attr4 ASC);
CREATE INDEX tb_one_idx_2 on tb_hit_feature (tb_hit_HitId ASC);
CREATE INDEX tb_two_idx_2 on tb_hit_source (tb_hit_HitId ASC);
这是QUERY PLAN(explain (analyse, buffers)
):
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
Merge Join (cost=3.85..287880.35 rows=1771004 width=44) (actual time=0.091..3894.024 rows=1726970 loops=1)
Merge Cond: (thf.tb_hit_hitid = ths.tb_hit_hitid)
Buffers: shared hit=354821
-> Index Scan using tb_one_idx_2 on tb_one thf (cost=0.43..124322.43 rows=3230800 width=52) (actual time=0.014..655.036 rows=1726946 loops=1)
Buffers: shared hit=27201
-> Index Scan using tb_two_idx_2 on tb_two ths (cost=0.43..139531.97 rows=1771004 width=8) (actual time=0.069..1604.789 rows=1726973 loops=1)
Filter: ((source)::text = ANY ('{source1,source2}'::text[]))
Rows Removed by Filter: 1651946
Buffers: shared hit=327620
Planning time: 2.737 ms
Execution time: 4117.573 ms
(11 rows)
答案 0 :(得分:0)
对于此查询:
SELECT thf.attr1, thf.attr2, thf.attr3, thf.attr4
FROM tb_one thf INNER JOIN
tb_two ths
ON ths.tb_hit_hitid = thf.tb_hit_hitid
WHERE ths.source IN ('source1', 'source2');
您需要tb_two(source, tb_hit_hitid)
和tb_one(tb_hit_hitid)
上的索引。这可能是最好的指数。
如果查询返回重复项(由于连接),我可能会建议将其写为:
SELECT thf.attr1, thf.attr2, thf.attr3, thf.attr4
FROM tb_one thf
WHERE EXISTS (SELECT 1
FROM tb_two ths
WHERE ths.tb_hit_hitid = thf.tb_hit_hitid AND
ths.source IN ('source1', 'source2')
);
对于此版本,您希望索引为tb_two(tb_hit_hitid, source)
。