SQL - извлечение строк по индексированному столбцу - производительность - PullRequest
0 голосов
/ 14 декабря 2018

У меня есть эта таблица с индексом для payment_id (не показан):

CREATE TABLE myschema.payments
(
 payment_id bigint NOT NULL,
 box_id bigint ,
 mov_id bigint ,
 code_co character varying(5) NOT NULL,
 client_id bigint NOT NULL,
 user_created character varying(15) NOT NULL,
 date_payment timestamp without time zone NOT NULL,
)
;

Эта таблица содержит около 30 миллионов записей

У меня есть такая тестовая таблица

insert into dummy_table (payment_id) values (294343, 5456565);

Анализ объяснения этого запроса возвращает результат примерно через 4 минуты:

select * from myschema.payments where payment_id in (select payment_id from dummy_table )

Однако, если я выполню что-то вроде этого:

select * from myschema.payments where 
payment_id in (294343, 5456565);

Я получурезультат в мс.

Эти значения payment_id являются переменными, как я могу улучшить производительность с переменным количеством различных payment_id при каждом выполнении?если это полезно, мой оператор «in» будет каждый раз иметь около 20 payment_id.

Это объяснение анализа запроса select * из myschema.payments, где payment_id in (select payment_id from dummy_table)

"Nested Loop Semi Join  (cost=100.00..6877.47 rows=137 width=274) (actual      time=47229.725..215893.809 rows=2 loops=1)"
"  Join Filter: (payments.payment_id = dummy_table.payment_id)"
"  Rows Removed by Join Filter: 47939387"
"  ->  Foreign Scan on payments  (cost=100.00..118.22 rows=274 width=274)      (actual time=1.334..198599.055 rows=23969695 loops=1)"
"  ->  Materialize  (cost=0.00..6751.03 rows=2 width=8) (actual time=0.000..0.000 rows=2 loops=23969695)"
"        ->  Seq Scan on dummy_table  (cost=0.00..6751.02 rows=2 width=8) (actual time=0.009..6.236 rows=2 loops=1)"
"Planning time: 0.238 ms"
"Execution time: 215894.462 ms"

EDIT: добавлен анализ объяснения для версии объединения:

select p.*
from myschema.payments p join
 dummy_table t
 on p.payment_id = t.payment_id;

"Nested Loop  (cost=100.00..6877.47 rows=3 width=274) (actual time=50680.577..228816.409 rows=2 loops=1)"
"  Join Filter: (payments.payment_id = dummy_table.payment_id)"
"  Rows Removed by Join Filter: 47939388"
"  ->  Foreign Scan on payments p  (cost=100.00..118.22 rows=274 width=274) (actual time=1.261..211380.739 rows=23969695 loops=1)"
"  ->  Materialize  (cost=0.00..6751.03 rows=2 width=8) (actual time=0.000..0.000 rows=2 loops=23969695)"
"        ->  Seq Scan on dummy_table t  (cost=0.00..6751.02 rows=2 width=8) (actual time=0.022..9.566 rows=2 loops=1)"
"Planning time: 0.311 ms"
"Execution time: 228817.094 ms"

1 Ответ

0 голосов
/ 14 декабря 2018

Попробуйте использовать join:

select p.*
from myschema.payments p join
     dummy_table t
     on p.payment_id = t.payment_id;

Попробуйте эту версию.,,что немного грубее:

select p.*
from dummy_table t left join
     myschema.payments p
     on p.payment_id = t.payment_id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...