Пересечь две таблицы размером 500 мл строк в Vertica - PullRequest
0 голосов
/ 19 января 2020

Я очень новичок в vertica db и, следовательно, ищу различные эффективные способы сравнения двух таблиц строк среднего размера 500ml-800ml в vertica. У меня есть процесс, который получает данные из представления vertica и выгружает на сервер SQL для последующего слияния с финальной таблицей на сервере sql. для нескольких больших таблиц в день сбрасывается около 3 млрд строк. Вместо сброса всех данных я хочу сделать ежедневный снимок и сравнить его со снимком предыдущих дней только на стороне vertica, а затем pu sh изменил только строки на SQL SEREVER.

скажем, предыдущий снимок хранится в таблице A, сегодняшний снимок хранится в таблице B. PK в обеих таблицах - это столбец с именем OrderId.

Самый простой способ, которым я могу придумать, это

Select * from tableB
Where OrderId NOT IN (

SELECT * from tableA
INTERSECT
SELECT * from tbleB
)

Итак, мои вопросы:

  1. Есть ли другие / лучший вариант в vertica, чтобы получить только измененные строки между двумя таблицами? Или я должен даже подумать о том, чтобы сделать это сравнение на стороне vertica?
  2. Сколько должно пройти такое сравнение?
  3. Что следует учитывать для повышения производительности такого запроса?

Ответы [ 3 ]

1 голос
/ 19 января 2020

Если ваши столбцы не имеют значений NULL, тогда массивный LEFT JOIN может показаться так, как вы хотите:

select b.*
from tableB b left join
     tableA a
     on b.OrderId = a.OrderId and
        b.col1 = a.col1 and
        . . .   -- for all the columns you care about

Однако я думаю, что вы хотите except:

select b.*
from tableB b
except
select a.*
from tableA a;

Я думаю, что это будет иметь разумную производительность.

1 голос
/ 19 января 2020

Вы также делаете это, используя соединения:

SELECT b.*
FROM tableB AS b 
LEFT JOIN tableA AS a ON a.id = b.id
WHERE a.id IS NULL

, поэтому вышеупомянутый запрос возвращает только diff из TableB в TableA, т.е. данные, которые присутствуют в обеих таблицах, будут пропущены ...

0 голосов
/ 20 января 2020

Есть ли у вас первичный ключ в двух таблицах?

Тогда моя методика для полного сбора данных об изменениях:

SELECT
 'I' AS to_do
, newrows.*
FROM tb_today     newrows
LEFT
JOIN tb_yesterday oldrows USING(id)
WHERE oldrows.id IS NULL
UNION ALL
SELECT
  'U' AS to_do
, newrows.*
FROM tb_today     newrows
JOIN tb_yesterday oldrows
WHERE oldrows.fname   <> newrows.fname
   OR oldrows.lnamd   <> newrows.lname
   OR oldrows.bdate   <> newrwos.bdate
   OR oldrows.sal     <> newrows.sal
 [...]
   OR oldrows.lastcol <> newrows.lastcol
UNION ALL
SELECT
 'D' AS to_do
, oldrows.*
FROM tb_yesterday oldrows
LEFT
JOIN tb_today     oldrows USING(id)
WHERE newrows.id IS NULL
;

Просто опустите последний отрезок UNION SELECT, если вы не хотите обслуживать DELETEs ('D')

Удачи

...