-2

我使用的是 PostgreSQL 8.1,并且我有两个数据库,其中一个表名客户端相同,每个客户端都包含 +-50k 行。

我需要在一个表中获取不在另一个表中的所有 id,我有以下解决方案

$sql = "SELECT id FROM clients WHERE id NOT IN(".pg_query($conn1,'SELECT id FROM clients').")";
$result = pg_query($conn2,$sql);

在我运行它之前,这是通过 PHP 实现它的好方法还是其他更好更快的方法?

不幸的是,我无法使用 dblink,因为我没有安装它的权限。

4

3 回答 3

1

数据库链接

您可以使用dblink在查询中引用来自另一个数据库的表。

然后您的查询可能如下所示(多种不同方法之一):

SELECT id
FROM   clients c
LEFT   JOIN (
    SELECT *
    FROM   dblink('dbname=mydb', 'SELECT id FROM clients')
    AS     c(id int)
    )  x USING (id)
WHERE  x.id IS NULL;

自 PostgreSQL 9.1 以来,安装附加模块变得更加简单:

CREATE EXTENSION dblink;

每个数据库运行一次。至于必要的特权

加载扩展需要创建其组件对象所需的相同权限。对于大多数扩展,这意味着需要超级用户或数据库所有者权限。

复制

如果 dblink(或类似的 x-db 工具对您不可用,请尝试使用COPYTO / FROM 传输外部表的内容:

在国外数据库中:

COPY clients TO '/path/to/file';

在家庭数据库中:

CREATE TEMP TABLE c_tmp (LIKE clients);
COPY c_tmp FROM '/path/to/file';

SELECT id
FROM   clients c
LEFT   JOIN c_tmp x USING (id)
WHERE  x.id IS NULL;

温度。表在会话结束时自动删除。

于 2012-11-16T14:49:10.253 回答
1

如果您不能使用数据库链接,我认为您将不得不在中间件中进行操作——并且该中间件应该有很多 RAM。

我也建议不要为此目的使用 PHP,但如果你没有其他可能性,我会这样做:

$ids = array();
$idsNotExist = array();
$resultDb1 = pg_query('SELECT id FROM db1');
while ( $row = pg_fetch_dontknowtheexactfunction_row($resultDb1) ) {
  array_push($ids, $row['id']);
}

$resultDb2 = pg_query('SELECT id FROM db2');
while ( $row = pg_fetch($resultDb2) ) {
  if ( !in_array($ids, $row['id']) ) {
    array_push($idsNotExist, $row['id']);
  }
}

最好的方法当然是,因为 ID 是主键,所以编写一个自己的 in_array 函数,该函数在找到 ID 时从 haystack 中删除它,因为它不会被再次搜索,并且下一个搜索循环会更快一些。

于 2012-11-16T15:12:57.757 回答
0
SELECT id
FROM db.clients
WHERE id NOT IN (
   SELECT id
   FROM otherdb.clients
)

一个查询。不需要多个数据库连接,除非您用于第一个连接的用户 ID 对其中一个表没有访问权限。SQL 允许完全绝对db.table.field类型规范以允许跨数据库查询。

于 2012-11-16T14:43:38.103 回答