в postgres, можно ли оптимизировать ВИД СОЮЗОВ - PullRequest
4 голосов
/ 06 января 2012

в базе данных есть много идентичных схем, cmp01 .. cmpa0

каждая схема имеет users таблицу

первичный ключ таблицы users каждой схемы имеет свойсобственный уникальный диапазон

, например, в cmp01.users usr_id находится между 0x01000000 and 0x01ffffffff.

. Есть ли какой-нибудь способ определить VIEW global.users, который является объединением каждоготаблиц cmp*.union таким образом, чтобы при запросе по usr_id оптимизатор направлялся бы к правильной схеме?

думал что-то вроде:

create view global.users as
select * from cmp01.users where usr_id between 0x01000000 and 0x01ffffffff
union all
select * from cmp02.users where usr_id between 0x02000000 and 0x02ffffffff
....

будет ли этоРабота?NO.EXPLAIN ANALYZE показывает все используемые схемы.

Есть ли подход, который может дать полезные советы оптимизатору?

Ответы [ 3 ]

2 голосов
/ 06 января 2012

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

create table all_users (
source_schema varchar(32),
usr_id int primary key,
-- other columns as per existing table(s)
);

Свернуть таблицу, вставив все строки:

insert into all_users
select 'cmp01', * from cmp01.users union
select 'cmp02', * from cmp02.users union ...; -- etc

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

Это не так сложно настроить, и он будет работать хорошо

1 голос
/ 06 января 2012

А как насчет создания многораздельной таблицы? Основная таблица будет создана как global.users и будет разделена по имени схемы.

Таким образом, вы получите маленькие пользовательские таблицы в каждой схеме (включая быстрый поиск), при условии, что вы сможете создавать запросы, которые PostgreSQL может оптимизировать, т.е. включать имя схемы в условии where. Вы также можете создать представление в каждой схеме, которое будет скрывать имя нужной схемы для запроса секционированных таблиц. Я не думаю, что это будет работать, указав только user_id. Я боюсь, что функции разделения PostgreSQL недостаточно умны для этого.

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

0 голосов
/ 06 января 2012

Попробуйте что-то вроде:

create view global.users as
select *
from (select 'cmp01' sel_schema, 0x01000000 usr_id_start, 0x01ffffffff usr_id_end
      union all
      select 'cmp02' sel_schema, 0x02000000 usr_id_start, 0x02ffffffff usr_id_end) s
join (select u1.*, 'cmp01' schema from cmp01.users u1
      union all
      select u2.*, 'cmp02' schema from cmp02.users u2) u
on s.sel_schema = u.schema 

и включают условие типа specified_usr_id between usr_id_start and usr_id_end при запросе представления по указанному идентификатору пользователя.

...