PostgreSQL 9.5.15 - Соединение влево с огромным столом занимает много времени - PullRequest
0 голосов
/ 24 октября 2019

Мне нужно ваше предложение по приведенной ниже проблеме производительности запросов.

  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, имеющая 100K записей.

CREATE TABLE tableB(  id bigint NOT NULL);

CREATE INDEX idx_tableB_id  ON tableB  USING btree (id);

Но таблица B имеет объем данных 145 ГБ.

Если я выполню запрос с одним левым соединением, как показано ниже,

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

, получая данные быстрее. Но когда я объединяю оба LEFT JOIN, тогда запрос занимает 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;

Получил индексы по соответствующим столбцам. Любые другие предложения по производительности для сокращения времени выполнения.

VERSION: "PostgreSQL 9.5.15 на x86_64-pc-linux-gnu, скомпилированный gcc (GCC) 4.8.2 20140120 (Red Hat 4.8.2-16), 64-разрядный "

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

1 Ответ

0 голосов
/ 24 октября 2019

Я подозреваю, что

  • B1.second_id либо не имеет индекса

  • B1.second_id не является уникальным (или первичным ключом)

  • B1.second_id является частью многоколоночного индекса, где он не является первым столбцом в индексе

Если у вас есть индексв этом столбце можно также попытаться переместить индексы на другой том, чтобы он не конфликтовал с извлечением основных данных.

Запустите EXPLAIN в своем запросе, чтобы убедиться, что индексы используются, а не возвращаются кпоследовательное сканирование тома объемом 145 ГБ.

Вы также не упомянули, сколько оперативной памяти имеется в вашей базе данных. Если ваши настройки в сочетании с вашим запросом делают перестановку системы, вы также можете увидеть резкое падение производительности.

...