INTERSECT vertica 中两个 table 大小为 500ml 的行

INTERSECT two table of size 500ml rows in vertica

我对 vertica db 很陌生,因此正在寻找不同的有效方法来比较 vertica 中两个平均大小为 500ml-800ml 的行的 tables。我有一个进程从 vertica 视图获取数据并转储到 SQL 服务器,以便稍后合并到 sql 服务器中的最终 table。对于少数大型 tables 组合,它每天倾倒大约 3bl 行。我不想转储所有数据,而是想拍摄每日快照,并将其与前几天的快照进行比较,仅在 vertica 端进行比较,然后仅将更改的行推送到 SQL SEREVER。

假设以前的快照存储在 tableA 中,今天的快照存储在 tableB 中。 table 上的主键是名为 OrderId 的列。

我能想到的最简单的方法是

Select * from tableB
Where OrderId NOT IN (

SELECT * from tableA
INTERSECT
SELECT * from tbleB
)

所以我的问题是:

  1. vertica 中是否有任何 other/better 选项来仅获取两个 table 之间更改的行?或者我应该 甚至考虑在 vertica 端进行比较?
  2. 做这样的比较需要多少钱?
  3. 我应该考虑什么来提高此类查询的性能?

你也可以很好地使用连接:

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

所以上面的查询 return 仅从 TableB 到 TableA 不同,即两个 table 中都存在的数据将被跳过...

如果您的列没有 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;

我想这会有合理的性能。

你这两个表有主键吗?

那么我的完整变更数据捕获技术是:

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
;

如果您不想满足 DELETE 的需要,请省略 UNION SELECT 的最后一段 ('D')

祝你好运