Skip to content

A way of creating computed columns with better performance #2551

Open
@the-sun-will-rise-tomorrow

Description

Summary

I implemented a number of computed columns as described on https://postgraphile.org/postgraphile/next/computed-columns - functions which accept an individual row, and return a value.

This works, however, as documented, it's slow. I think the problem is not so much because it's a function, but because if the function needs to fetch additional data from other tables using a sub-query, then PostgreSQL cannot optimize this sub-query into something more efficient such as a hoisted JOIN.

I tried a different approach as well. Instead of using functions, I declared a view which used CTEs to return all data and all computed columns as a single view. Unfortunately, this seems to cause PostgreSQL to eagerly compute all such computed columns, whether they are required from the Postgraphile's GraphQL selection set or not, so while it did help significantly in some situations, it introduced significant overhead in others.

I am wondering if it would be possible to have a more efficient general purpose way of defining computed columns, where the building block is not a function, but a view which returns two columns: id and value. This would then be joined by PostGraphile with the main table as needed.

CREATE TABLE people (id integer, name text, birth_date date);

CREATE VIEW people_age AS
SELECT
  id,
  DATE_PART('year', AGE(birth_date, NOW())) AS value
FROM 
  people;
COMMENT ON VIEW people_age IS $$
@computed_column_single  # returns exactly one value per data row ID; could also be:
# @computed_column_maybe_single  # returns zero or one value per data row, visible in GraphQL as a nullable value
# @computed_column_many  # returns any number of values per data row, visible in GraphQL as an array of values
@joined_on id
$$;

What do you think? Does this already exist somewhere?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    🌳 Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions