У меня есть таблица с 14 миллионами строк.Я пытаюсь получить своего рода «список краев», где я могу наблюдать, если данные сканирования находятся в пределах времени дельты от всех других наблюдений.Попытка выполнить запрос для 1% выборки данных заняла час.С 5% прошло более 12 часов.Минимальный пример задачи:
Исходная таблица
+----------+------------+------------+------------+
| ID | SCANDATE | SCANDATE+D | SCANDATE-D |
+----------+------------+------------+------------+
| A | 2018/08/03 | 2018/08/05 | 2018/08/01 |
| B | 2018/08/04 | 2018/08/06 | 2018/08/02 |
| C | 2018/08/11 | 2018/08/13 | 2018/08/09 |
+----------+------------+------------+------------+
РЕЗУЛЬТАТ:
+----------+------------+
| ID1 | ID2 |
+----------+------------+
| A | B |
+----------+------------+
Я использую следующий код:
CREATE TABLE edgelist_1 AS (SELECT * FROM
(SELECT scan_date, ship_date, serial_number,scan_date
+ interval '3' day AS buffup, scan_date - interval '3'
day AS bufflow FROM bag_list_1 ) AS ims
INNER JOIN
( SELECT
scan_date as buff, serial_number as SN FROM bag_list_1 )
AS X
ON ims.serial_number<>X.SN
WHERE ims.bufflow < X.buff AND ims.buffup > X.buff )
Это вывод Объяснения, который я получаю:
Gather (cost=1000.00..4596699470013.62 rows=21994769623450 width=62)
Workers Planned: 4
-> Nested Loop (cost=0.00..2397222506668.62 rows=5498692405862 width=62)
Join Filter: ((bag_list_1.serial_number <> bag_list_1_1.serial_number) AND ((bag_list_1.scan_date - '3 days'::interval day) < bag_list_1_1.scan_date) AND ((bag_list_1.scan_date + '3 days'::interval day) > bag_list_1_1.scan_date))
-> Parallel Seq Scan on bag_list_1 (cost=0.00..251629.94 rows=3517394 width=27)
-> Seq Scan on bag_list_1 bag_list_1_1 (cost=0.00..357151.75 rows=14069575 width=19)
Какой более эффективный способ выполнить эту задачу.