我需要您对以下查询性能问题的建议。
CREATE TEMPORARY TABLE tableA( id bigint NOT NULL, second_id bigint );
CREATE INDEX idx_tableA_id ON tableA USING btree (id);
CREATE INDEX idx_tableA_second_id ON tableA USING btree (second_id);
这里表A具有10万条记录。
CREATE TABLE tableB( id bigint NOT NULL);
CREATE INDEX idx_tableB_id ON tableB USING btree (id);
但是表B的数据量为145GB。
如果我使用一个左连接执行查询,如下所示,
select a.id from table A left join table B on B.id = A.id
或
select a.id from table A left join table B on B.d_id = A.Second_id
更快地获取数据。但是,当我同时将两个左联接合并时,查询将花费30分钟来查询记录。
SELECT a.id
FROM tableA A LEFT JOIN tableB B on B.id = A.id
LEFT JOIN tableB B1 on B1.id = A.second_id;
获得相应列上的索引。其他可减少执行时间的性能建议。
Execution plan
Hash Right Join (cost=18744968.20..108460708.81 rows=298384424 width=8) (actual time=469896.453..1290666.446 rows=26520 loops=1)
Hash Cond: (tableB.id = tableA.id)
-> Seq Scan on tableB ubp1 (cost=0.00..63944581.96 rows=264200740 width=8) (actual time=127.504..1182339.167 rows=268297289 loops=1)
Filter: (company_type_id = 2)
Rows Removed by Filter: 1409407086
-> Hash (cost=18722912.16..18722912.16 rows=1764483 width=8) (actual time=16564.303..16564.303 rows=26520 loops=1)
Buckets: 2097152 Batches: 1 Memory Usage: 17420kB
-> Merge Join (cost=6035.58..18722912.16 rows=1764483 width=8) (actual time=37.964..16503.057 rows=26520 loops=1)
-> Nested Loop Left Join (cost=0.86..18686031.22 rows=1752390 width=8) (actual time=0.019..16412.634 rows=26520 loops=1)
-> Index Scan using idx_tableA_id on tableA A (cost=0.29..94059.62 rows=26520 width=16) (actual time=0.013..69.016 rows=26520 loops=1)
-> Index Scan using idx_tableB_id on tableB B (cost=0.58..699.36 rows=169 width=8) (actual time=0.458..0.615 rows=0 loops=26520)
Index Cond: (tableA.id = tableB.second_id)
Filter: (company_type_id = 2)
Rows Removed by Filter: 2
-> Sort (cost=6034.21..6100.97 rows=26703 width=8) (actual time=37.941..54.444 rows=26520 loops=1)
Rows Removed by Filter: 105741
Planning time: 0.878 ms
Execution time: 1290674.154 ms
感谢和问候,Thiru.M
我怀疑
B1.second_id都没有索引
B1.second_id不是唯一的(或主键)
B1.second_id是多列索引的一部分,其中不是索引的第一列
如果在该列上有索引,则也可以尝试将索引移到其他卷,以免与主要数据检索发生争用。
对查询运行EXPLAIN来验证正在使用索引,而不是退回到145GB卷上的顺序扫描。
您也没有提到数据库有多少可用RAM。如果您的设置与查询结合在一起会导致系统交换,那么性能也会急剧下降。