Запрос из двух таблиц с исключением

Latrekc

Новичок
Запрос из двух таблиц с исключением

Задача в принципе аналогичная этой. Нужно из одной таблицы взять данные отсутвующие во второй и положить в эту вторую. Т.е. что то типа
PHP:
INSERT INTO b (SELECT * FROM a WHERE a.id != b.id)
или
PHP:
INSERT INTO b (SELECT * FROM a WHERE a.id NOT IN (b.id))
Вся проблема в том что в одной таблице примерно 55 000 записей, а в другой примерно 105 000. Т.е. приведенный выше запрос будет выполнятся довольно долго
 

nickg

Guest
Во-первых, использовать версию не ниже 7.4, где IN работает с индексами, а не с полным сканом. Естественно, id -- это первичный ключ в обеих таблицах, да? Обязательно ANALYZE обеих таблиц перед вставкой.

И тогда попробовать
INSERT INTO b (SELECT * FROM a WHERE id NOT IN (SELECT id FROM b))

Но, повторяю, IN -- это только для 7.4 и выше. Для более ранних надо переписывать с EXISTS.

Сначала сделать EXPLAIN, чтобы оценить план выполнения.
 

Latrekc

Новичок
Да, уникальный ключ стоит. Правда только на одной из таблиц.

Скорее всего я в php отберу нужные записи, так как эта синхронизация будет производится не чаще чем раз в неделю.
 

nickg

Guest
Думаешь, отобрать все данные, перегнать их через сокет между процессами, посчитать и перегнать нужное обратно быстрее, чем отобрать по индексу и обновить прямо внутри СУБД, без межпроцессного обмена?

Кстати, можно повесить триггер, который будет всегда держать таблицы одинаковыми.

Только зачем две одинаковые таблицы, непонятно. Может, подумать о перепроектировании?
 

nickg

Guest
Между разными базами данных нельзя делать запросы (не считая contrib/dblink, но там все иначе).

Или имеются в виду разные программы? Так это наоборот надо делать на одной базе. Хранилище данных одно, программы разные, и это правильно.
 

Latrekc

Новичок
Базы данных разные, хотя и на одной машине и программа одна (PostgreSQL 7.4). В базах контент двух наших проектов, в частности у каждого есть таблица с пользователями/подписчиками на новости. Рассылка новостей осуществляется только с одного из проектов, соответсвенно небходимо из второго проекта дергать пользователей, которые подписались на новости этих проектов. Я планировал дернуть таблицу с пользователями из одного из проектов с помощью pg_dump, закачать ее в какую то временную таблицу второго проекта. И потом уже с помощью SQL запросов скопировать пользователей отсутвующих во второй базе.

-~{}~ 29.11.04 14:31:

Да, фокус еще и в том что не все столбцы в этих таблицах совпадают.
 

nickg

Guest
А отчего бы не держать все в одной базе, но в разных схемах? Так гораздо удобнее, и многое упрощает.
 

Latrekc

Новичок
Овчинка выделки не стоит. Из за подобной ерунды переписывать движок совершенно не хочется. Тем более он с претензией на универсальность и все такое, а 2 проекта в одной базе это явный "нестандарт".
 

nickg

Guest
Пользователи Potgres разные, можно задать путь поиска по схемам в свойствах пользователя. Тогда ничего не нужно переписывать.

Впрочем, ладно, вам решать.
 

Latrekc

Новичок
Под пользователями я не имел ввиду пользователей базы данных, это объекты которые строятся на основе записей таблицы suser (или какой то другой таблицы, это не принципиально)
 

nickg

Guest
Это я понял. И я здесь имел в виду как раз пользователей базы данных.

Ладно, фиг с ним. Похоже мы друг друга не понимаем, да и не надо это вам.
 

Latrekc

Новичок
Мда, действительно я не догнал о чем вы говорили.
Я почему то думал что в разных схемах мы не можем использовать таблицы с одинаковыми именами.
 

nickg

Guest
Конечно, можете! На то и существуют схемы, они же пространства имен (namespaces).
 
Сверху