代码之家  ›  专栏  ›  技术社区  ›  MB34

直接查询Postgres继承表

  •  0
  • MB34  · 技术社区  · 6 年前

    Postgres允许您使用继承创建表。我们有一个设计,其中有1400个表继承自一个主表。这些表格适用于我们每个供应商的库存。

    当我想查询供应商的库存时,我只查询主表。运行时 Explain 解释说它正在遍历所有1400个索引和相当多的继承表。这会导致查询运行非常缓慢。如果我只查询供应商的库存表,我会通过查询主表将查询时间缩短到不足50%。

    我们在另一个表上有一个join,它为供应商的合作伙伴供应商提取标识符,我们还想查询他们的库存。例子:

    SELECT 
        (select m2.company from sup.members m2 where m2.id = u.id) as company,  
        u.id,
        u.item, 
        DATE_PART('day', CURRENT_TIMESTAMP - u.datein::timestamp) AS daysinstock, 
        u.grade as condition, 
        u.stockno AS stocknumber, 
        u.ic, 
        CASE WHEN u.rprice > 0 THEN 
            u.rprice 
        ELSE 
            NULL 
        END AS price, 
        u.qty
    FROM pub.net u 
    LEFT JOIN sup.members m1 
        ON m1.id = u.id OR u.id = any(regexp_split_to_array(m1.partnerslist,',')) 
    WHERE u.ic in ('01036') -- part to query
      AND m1.id = 'N40'     -- vendor to query
    

    N40_stock表中有id=N40的供应商的库存,N40的合作伙伴供应商(partnerslist)是g01、g06、g21、k17、n49、v02、m16,因此我也希望 查询g01_stock、g06_stock、g21_stock、k17_stock、n49_stock、v02_stock和m16_stock表。

    我知道only子句,但是是否可以修改这个查询以仅从特定继承的表中获取数据?

    编辑
    这会将时间缩短到800毫秒以下,但我希望减少:

    WITH cte as (
        SELECT partnerslist as a FROM sup.members WHERE id = 'N40' 
    ) 
    SELECT 
        (select m2.company from sup.members m2 where m2.id = u.id) as company,
        u.id,
        u.item, 
        DATE_PART('day', CURRENT_TIMESTAMP - u.datein::timestamp) AS daysinstock, 
        u.grade as condition, 
        u.stockno AS stocknumber, 
        u.ic, 
        CASE WHEN u.rprice > 0 THEN 
            u.rprice 
        ELSE 
            NULL 
        END AS price, 
        u.qty
    FROM pub.net u 
    WHERE u.ic in ('01036') -- part to query
      AND u.id = any(regexp_split_to_array('N40,'||(select a from cte), ','))
    

    我无法从 cte 因为我需要U.ID中的一个,当合作伙伴在WHERE子句中更改时这是不同的。

    1 回复  |  直到 6 年前
        1
  •  0
  •   eatmeimadanish    6 年前

    继承的表查找基于映射到检查表约束的实际WHERE子句。仅仅继承表是不够的。

    https://www.postgresql.org/docs/9.6/static/ddl-partitioning.html

    注意,如果原始查询中没有实现实际值,则不能使用动态创建的变量。这将检查所有继承的表。