-2

私はPostgreSQL8.1を使用しており、1つのテーブル名が同一でそれぞれ+-50k行を含むクライアントを持つ2つのデータベースがあります。

一方のテーブルでもう一方のテーブルにないすべてのIDを取得する必要があります。次の解決策があります。

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

これを実行する前に、これはPHPを介して実行するための良い方法ですか、それとも他のより高速な方法ですか?

残念ながら、dblinkをインストールする権限がないため、dblinkを使用できません。

4

3 に答える 3

1

dblink

dblinkを使用して、クエリ内の別のデータベースのテーブルを参照できます。

次に、クエリは次のようになります(複数の異なるアプローチの1つ)。

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;

データベースごとに1回実行します。必要な特権について:

拡張機能をロードするには、そのコンポーネントオブジェクトを作成するために必要な権限と同じ権限が必要です。ほとんどの拡張機能では、これはスーパーユーザーまたはデータベース所有者の特権が必要であることを意味します。

コピー

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が主キーであるため、IDが再度検索されることはなく、次の検索ループが少し速くなるため、IDが見つかったときにhaystackからIDを削除する独自のin_array-functionを作成するのが最善の方法です。

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

1つのクエリ。最初の接続に使用したユーザーIDに、これらのテーブルの1つに対するアクセス権がない場合を除いて、複数のデータベース接続は必要ありません。SQLでは、完全に絶対的なdb.table.field型の指定が可能であり、データベース間のクエリが可能です。

于 2012-11-16T14:43:38.103 に答える