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
)
所以我的问题是:
- vertica 中是否有任何 other/better 选项来仅获取两个 table 之间更改的行?或者我应该
甚至考虑在 vertica 端进行比较?
- 做这样的比较需要多少钱?
- 我应该考虑什么来提高此类查询的性能?
你也可以很好地使用连接:
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')
祝你好运
我对 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
)
所以我的问题是:
- vertica 中是否有任何 other/better 选项来仅获取两个 table 之间更改的行?或者我应该 甚至考虑在 vertica 端进行比较?
- 做这样的比较需要多少钱?
- 我应该考虑什么来提高此类查询的性能?
你也可以很好地使用连接:
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')
祝你好运