Search Postgresql Archives

Re: Using indexes through a plpgsql procedure

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2021-04-07 12:15:37 +0100, Ciaran Doherty wrote:
> As a quick question. Can Postgres make use of indexes on a table when the data
> from that table is being returned from a procedure?
> 
> Some more details. I have a big table which has a long running query running on
> it. This table gets rebuilt from scratch on a weekly basis. Currently, I cannot
> update/replace the table in a timely manner, I have to wait for the long
> running queries to finish before we can update the table (the total time can be
> 5+ hours).
> 
> I am currently trying to build a procedure which will return data from the
> latest version of the table (by dynamically choosing the table name, something
> like
> https://stackoverflow.com/questions/35559093/
> how-to-use-variable-as-table-name-in-plpgsql)

So you are creating a new table for each update and drop older tables
after some time? And your procedure just returns data from the newest
table?


>   . To get a consistent return type I am having to use the `create
> type`  to build a custom return type. The problem (I think) I am
> having is that the indexes on the underlying tables are not usable
> after calling this procedure
> 
> (e.g.
> ```
> select *
>   from example_table as et
>     join example_procedure() as ep on et.exapmle_column = ep.example_column
> ```
> there will be no index on the column ep.example_column)
> 
> Is there a way to make sure indexes are used even if the data is accessed threw
> a procdure?

Any query within example_procedure() will be able to use an index. and
the join will in theory be able to use an index on example_table, although it
can't really get useful statistics (it doesn't know what fraction of the
example_table will be covered by the output of example_procedure()), so
it might default to doing a full scan anyway.

I would probably use a view for this: After creating the new table, just
recreate the view to use the new table. 

Or maybe you don't even need the view and can get away by renaming the
old and new table:

begin;
    create table ep_new(...);
    -- populate ep_new here
    drop table if exists ep_old;
    alter table ep rename to ep_old;
    alter table ep_new rename to ep;
commit;

Partitioning should also work but that feels like a hack.

        hp


-- 
   _  | Peter J. Holzer    | Story must make more sense than reality.
|_|_) |                    |
| |   | hjp@xxxxxx         |    -- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |       challenge!"

Attachment: signature.asc
Description: PGP signature


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]

  Powered by Linux