How can I prevent Postgres from inlining a subquery?

后端 未结 2 1143
刺人心
刺人心 2020-12-20 14:18

Here\'s a slow query on Postgres 9.1.6, even though the maximum count is 2, with both rows already identified by their primary keys: (4.5 seconds)

EXPLAIN AN         


        
2条回答
  •  孤城傲影
    2020-12-20 14:35

    I think OFFSET 0 is the better approach since it's more obviously a hack showing that something weird is going on, and it's unlikely we'll ever change the optimiser behaviour around OFFSET 0 ... wheras hopefully CTEs will become inlineable at some point CTEs became inlineable by default in PostgreSQL 12. The following explanation is for completeness's sake; use Seamus's answer.

    For uncorrelated subqueries you could exploit PostgreSQL 11 and older's refusal to inline WITH query terms to rephrase your query as:

    WITH t AS (
        SELECT * FROM tbl WHERE id IN ('6d48fc431d21', 'd9e659e756ad')
    )
    SELECT COUNT(*) 
    FROM t 
    WHERE data ? 'building_floorspace' 
    AND data ?| ARRAY['elec_mean_monthly_use', 'gas_mean_monthly_use'];
    

    This has much the same effect as the OFFSET 0 hack, and like the offset 0 hack exploits quirks in Pg's optimizer that people use to get around Pg's lack of query hints ... by using them as query hints.

    But the OFFSET 0 hack is somewhat officially blessed, wheras CTE abuse doesn't work anymore in PostgreSQL 12. (Yay!).

提交回复
热议问题