Vous n'êtes pas identifié(e).
Pages : 1
Bonjour,
J'ai une requête qui ne veut pas "envoyer son where" au serveur distant (en v10.4 des 2 cotés, même machine, en debian stable).
C'est un filtre "similarity" : where (column % search)
La colonne est indéxée, pas de souci sur la base en direct...
L'explain montre : Remote SQL: SELECT column FROM public.table
et donc malheureusement, ça filtre en local: Rows Removed by Filter: 249486 :-(
J'ai pourtant précisé "extensions 'pg_trgm'" dans le "create server", ce qui est nécessaire pour que pg pousse les filtres sur le serveur distant...
Est-ce un bug ?
Hors ligne
Bon, je crois avoir trouvé une solution: ce n'est que si les fonctions sont immutables qu'elles peuvent être déportées (dixit la doc).
En faisant un simple "alter function similarity_op(text,text) immutable;" (au lieu de stable) sur la base cible et la base contenant le fdw, le sql envoyé est bien celui avec le filtre !
Et je divise par 10 le temps d'éxécution, ce qui m'arrange bien car pour un affichage de suggestions dans un champ de saisie, devoir attendre 2/3 secondes, c'était pas glop !
Hors ligne
Elle n'est pas immutable sans doute parce que le résultat dépend du paramètre pg_trgm.similarity_threshold.
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
Ah, oui, du coup, je viens de me rendre compte que je ne peux pas "envoyer" un autre threshold à la base distante :-(
(à moins que le fdw se connecte par un utilisateur dédié sur lequel on aurait fait un "alter role set th=0.1")
Qu'est ce que ça implique de passer cette fonction en immutable ? (je n'ai pas besoin d'une vue "stable" des données, c'est pour faire des recherches de titres de films...)
Dernière modification par mgmpg (18/05/2018 15:04:42)
Hors ligne
J'ai trouvé un "hack" pour faire passer le similarity_threshold à la base distante: dans celle-ci, je crée plusieurs vues qui font simplement un "select set_limit()" et j'appelle la bonne vue distante avant ma vraie requete distante avec l'opérateur "%" => ça fonctionne mais il ne faudrait pas que set_limit disparaisse (marquée comme deprecated dans la doc !)
Voici une fonction qui crée autant de vues que de valeurs de similarity souhaitées:
create or replace function fc_create_set_fdw_pgtrgm_similarity_views(
param_view_name_prefix text, -- can be schema prefixed, _nnn will be added after this name, ie _065 for 0.65 value
param_from_value float, -- 0 to 1
param_to_value float,
param_step float
) returns setof text as $$
declare
curr_value numeric(3,2);
view_name text;
sql_cmd text;
begin
curr_value=param_from_value;
while (curr_value<=param_to_value) loop
view_name=param_view_name_prefix||'_'||to_char(curr_value*100,'FM000');
--
sql_cmd='drop view if exists '||view_name||' cascade';
execute sql_cmd;
--
sql_cmd='create or replace view '||view_name||' as select set_limit('||to_char(curr_value,'FM0.00')||')'; -- TODO: set_limit() is currently deprecated
execute sql_cmd;
return next sql_cmd;
--
perform fc_comment_on('view',view_name,
'View that just set the pg_trgm.similarity_threshold value (only way to set it for a remote fdw query with the % operator!)',current_setting('sessionvar.version',true));
--
curr_value=curr_value+param_step;
end loop;
--
return;
end; $$
language plpgsql;
Idéalement, if faudrait pouvoir envoyer un "SET" à une base distante, y'a du patch en cours à ce sujet ?
Hors ligne
Pour que l'envoi d'un SET ait du sens, il faudrait s'assurer que toutes les requêtes de la session utilisent la même connexion. Même si postgres_fdw essaie de conserver sa connexion sur une même session, il n'y a aucune garantie que ce soit le cas. En dehors de ce petit problème technique, il n'y a aucun patch en cours à ce sujet à ma connaissance.
Guillaume.
Hors ligne
Pages : 1