Цель: создать отчетный Postgres экземпляр для конечного количества других postgres экземпляров. Все экземпляры имеют таблицу структуры каталогов и таблицу томов. Проблема в том, что таблица томов для всех начинается с индекса 1 для первого тома (автоинкремент). Все удаленные таблицы (использующие FDW) являются правильными индексами для быстрого поиска по volume_id. Итак, каков наилучший способ создать представление, которое включает в себя внешние таблицы, которые позволяют запрашивать, где volume_id может быть одинаковым, но имя тома может быть совершенно другим. Один из возможных ответов - создать смещение на лету, но это выглядит медленно
Упрощенная схема для таблицы томов:
id bigint
name text
Упрощенная схема для таблицы каталогов:
id bigint
path text
volume_id bigint
parent bigint
name text
чтобы получить все тома для тома Foo:
select d.* from directories d INNER JOIN volumes v on v.id = d.volume_id WHERE v.name = 'Foo';
представлений для объединения внешних каталогов:
create view volumes AS (select * from f1_volumes UNION SELECT id + 10000, name FROM f2_volumes);
create view directories AS (select * from f1_directories UNION SELECT id, path, volume_id + 10000, parent name FROM f2_directories);
В идеале запросы должны попадать в индексы на удаленном компьютере, чтобы при Я запускаю запрос с совпадающим томом.name на remote1, который будет быстрым, а также удаленным 2, но он чертовски медленен по сравнению с выполнением двух запросов FDW независимо (по причинам, связанным с местом, где происходит соединение)
Например,
select d.* from directories d INNER JOIN volume v on v.id = d.volume_id where v.name = 'vol1' limit 10; -- super slow; kills the indexes;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=467.88..478.03 rows=5 width=336)
-> Hash Join (cost=467.88..478.03 rows=5 width=336)
Hash Cond: ("*SELECT* 1".volume_id = v.id)
-> Unique (cost=242.28..247.50 rows=454 width=336)
-> Sort (cost=242.28..242.51 rows=454 width=336)
Sort Key: "*SELECT* 1".id, "*SELECT* 1".valid, "*SELECT* 1".volume_id, "*SELECT* 1".parent_id, (("*SELECT* 1".depth)::integer), (("*SELECT* 1".inode)::numeric), (("*SELECT* 1".size)::bigint), (("*SELECT* 1".blocks)::bigint), (("*SELECT* 1".ctime)::timestamp with time zone), (("*SELECT* 1".atime)::timestamp with time zone), (("*SELECT* 1".mtime)::timestamp with time zone), (("*SELECT* 1".uid)::bigint), (("*SELECT* 1".gid)::bigint), (("*SELECT* 1".perms)::integer), "*SELECT* 1".path, "*SELECT* 1".name, "*SELECT* 1".rec_aggrs, "*SELECT* 1".local_aggrs, "*SELECT* 1".history_id, (("*SELECT* 1".sync_time)::timestamp with time zone), (("*SELECT* 1".out_of_sync_time)::timestamp with time zone), "*SELECT* 1".errors
-> Append (cost=100.00..238.27 rows=454 width=336)
-> Subquery Scan on "*SELECT* 1" (cost=100.00..119.08 rows=227 width=336)
-> Foreign Scan on dir_current (cost=100.00..116.81 rows=227 width=336)
-> Subquery Scan on "*SELECT* 2" (cost=100.00..119.19 rows=227 width=336)
-> Foreign Scan on dir_current dir_current_1 (cost=100.00..116.92 rows=227 width=336)
-> Hash (cost=225.58..225.58 rows=2 width=8)
-> Subquery Scan on v (cost=225.54..225.58 rows=2 width=8)
-> Unique (cost=225.54..225.56 rows=2 width=289)
-> Sort (cost=225.54..225.54 rows=2 width=289)
Sort Key: volume.id, volume.name, volume.inode, volume.check_noatime, volume.store_cifs_acl, volume.store_posix_acl, volume.dir_excludes, volume.file_excludes, volume.total_capacity, volume.capacity_set_manually, volume.default_agent_address, volume.display_name, volume.free_space, volume.free_space_set_manually, volume.type
-> Append (cost=100.00..225.54 rows=2 width=289)
-> Foreign Scan on volume (cost=100.00..112.76 rows=1 width=289)
-> Foreign Scan on volume volume_1 (cost=100.00..112.76 rows=1 width=289)
(19 rows)
Есть ли какие-либо советы о том, как сделать это с помощью скорректированных смещений для volume_id и по-прежнему использовать индексы? Я понимаю, что соединение происходит здесь в неоптимальном месте, после объединения, где мы не можем использовать удаленные индексы для volume_id, и мне, вероятно, нужно будет просто создать представления с объединенным в них именем. Но, конечно, любая групповая операция, вероятно, будет иметь похожие, ужасные результаты.