user
Mientras reescribía su función, me di cuenta de que agregó alias de columna aquí:
SELECT
...
auth_user.email AS user,
customers.name AS customer,
.. que no haría nada para empezar, ya que esos alias son invisibles fuera de la función y no están referenciados dentro de la función. Así serían ignorados. Para fines de documentación, mejor use un comentario.
Pero también hace que su consulta sea inválida , porque user
es una palabra completamente reservada y no se puede usar como alias de columna a menos que esté entre comillas dobles.
Curiosamente, en mis pruebas, la función parece funcionar con el alias no válido. Probablemente porque es ignorado (?). Pero no estoy seguro de que esto no pueda tener efectos secundarios.
Tu función reescrita (de lo contrario, equivalente):
CREATE OR REPLACE FUNCTION get_web_events_by_userid(int)
RETURNS TABLE(
id int
, time_stamp timestamptz
, description text
, origin text
, userlogin text
, customer text
, client_ip inet
) AS
$func$
SELECT w.id
, w.time_stamp
, w.description
, w.origin
, u.email -- AS user -- make this a comment!
, c.name -- AS customer
, w.client_ip
FROM public.auth_user u
JOIN public.auth_web_events w ON w.user_id_fk = u.id
JOIN public.customers c ON c.id = u.customer_id_fk
WHERE u.id = $1 -- reverted the logic here
ORDER BY w.id DESC
$func$ LANGUAGE sql STABLE;
Obviamente, el STABLE
palabra clave cambió el resultado. Volatilidad de la función no debería ser un problema en la situación de prueba que describe. La configuración normalmente no beneficia a una sola llamada de función aislada. Lea los detalles en el manual. Además, estándar EXPLAIN
no muestra planes de consulta de lo que sucede dentro funciones Podría emplear el módulo adicional explicación automática por eso:
- Plan de consulta de Postgres de una invocación de UDF escrita en pgpsql
Tienes una distribución de datos muy extraña :
La tabla auth_web_events tiene 100000000 registros, auth_user->2 registros, clientes-> 1 registro
Como no definió lo contrario, la función asume una estimación de 1000 filas ser devuelto. Pero su función en realidad solo devuelve 2 filas . Si todas sus llamadas solo devuelven (cerca de) 2 filas, simplemente declare eso con un ROWS 2
agregado . Podría cambiar el plan de consulta para el VOLATILE
variante también (incluso si STABLE
es la elección correcta de todos modos aquí).