Estou trabalhando em um gateway de armazenamento multilocatário.
Cada inquilino tem seu próprio esquema -- o esquema para cada inquilino é um meta-esquema, então cada esquema de inquilino é idêntico. As interações do banco de dados ocorrem apenas por meio de uma API de procedimento armazenado. A camada de procedimento armazenado está no esquema público. Os procedimentos armazenados dependem do search_path sendo definido como <TENANT_SCHEMA>;public
.
A camada de aplicativo prepara instruções em relação aos procedimentos armazenados no esquema público.
Eu tenho um procedimento armazenado para alternar o locatário que se parece com o seguinte:
CREATE OR REPLACE FUNCTION domains_switch(domain DOMAIN_NAME) RETURNS VOID AS $$ BEGIN
IF EXISTS (SELECT NULL FROM public.domains WHERE domain_name = domain) THEN
EXECUTE format('set search_path=%s,public;', domain);
ELSE
RAISE 'domain "%" does not exist',domain USING ERRCODE = 'AX001';
END IF;
RETURN; END;
$$ LANGUAGE plpgsql;
plpgsql
os procedimentos armazenados gerenciam os próprios planos, o que significa que só preciso preparar as instruções da API uma vez por back-end no gateway. Suspeito que os planos em cache internos do procedimento armazenado sejam invalidados quando alterno o esquema.
Estou planejando adicionar uma camada ao gerenciamento do pool de conexões do gateway para minimizar os switches search_path. Minha intuição está correta? Esta é a coisa certa a fazer?
Eu diria que sua intuição está correta. Alterar as
search_path
causas do Postgres para começar do zero com instruções preparadas. O manual sobrePREPARE
:E instruções SQL dentro de funções PL/pgSQL são tratadas como instruções preparadas.
Especialmente ao trabalhar com poolers de conexão (a mesma conexão permanece aberta), isso ajudará no desempenho se você continuar alternando
search_path
para o mínimo.O custo extra não é muito alto para instruções simples, mas pode ser um efeito perceptível para consultas mais complexas.