【问题标题】:Table A except Table B (relating more than one column)除表 B 外的表 A(涉及多于一列)
【发布时间】:2012-10-31 15:01:57
【问题描述】:

我查询成功了:

SELECT * FROM tableA
WHERE NOT (column1 IN 
(SELECT column1 FROM tableB) AND columnDate='9999-12-31');

tableA 有大约 35000k(3500 万)条记录,tableB 有 5k(5000)条记录。 我在不到 5 分钟的时间内从 tableA 检索到除 tableB 之外的所有记录。

问题是当我尝试(对于另一个具有相同记录量的示例)使用 3 列(键)来实现相同的结果时:

SELECT * FROM tableA
WHERE NOT (column1 || column2 || column3 IN 
(SELECT column1 || column2 || column3 FROM tableB) AND columnDate='9999-12-31');

我在 1 小时 40 分钟内从 tableA 检索除 tableB 之外的所有记录......!

我可以更有效地查询它吗?

【问题讨论】:

  • 是一次性查询吗?你能在 tableB 上的column1 || column2 || column3 上创建一个索引吗?
  • 我为三列(A、B、C)创建了一个索引。结果没有区别。然后我尝试使用管道创建索引但检索到语法错误...
  • 不,在 a、b 和 c 上创建单独的索引不会削减它。您需要在 а || 上创建一个基于函数的索引。乙 || C。试试CREATE INDEX idx ON tableA (a || b || c);
  • 我认为发帖者对 || 并不真正感兴趣乙 || c,但 (a, b, c) 是否在第二个表中。
  • Podiluska,我正在查询一个 greenplum 数据库

标签: sql


【解决方案1】:
SELECT * FROM tableA a
WHERE NOT EXISTS
(SELECT null FROM tableB where a.column1=column1 and a.column2=column2 and a.column3=column3)
AND columnDate<>'9999-12-31'

【讨论】:

  • 这加上tableB上的索引(column1,column2,column3)
  • 缺少一些东西:我原来的 1h40m 查询返回 63.465.598 条记录(正确)。这个返回 22.280.920
  • @user1788913 如您所见,两个查询返回相同的结果,您的查询返回不同的结果。我怀疑我们没有在问题中得到正确的信息。你确定你奇怪的列 columndate 是它应该在的地方吗?
  • @user1788913 也许您不是在寻找 3 列的组合,请尝试在子选择中将 2 'and' 替换为 'or'
【解决方案2】:

一种方法是过滤左连接:

select  * 
from    tableA a
left join
        tableB b
on      b.col1 = a.col1
        and b.col2 = a.col2
        and b.col3 = a.col3
where   a.columnDate <> '9999-12-31'
        and b.id is null -- No match found in B

【讨论】:

  • tableB中的id列代表什么?
  • tableB 中的主键(或任何其他不可为空的列)。
  • 缺少一些东西:我原来的 1h40m 查询返回 63.465.598 条记录(正确)。这个返回 22.280.920
猜你喜欢
  • 1970-01-01
  • 2011-02-22
  • 2014-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多