PostgreSQL代码优化

PostgreSQL代码优化,sql,database,performance,postgresql,Sql,Database,Performance,Postgresql,我有以下代码: SELECT rv_storage.m_product_id AS n_product_id, rv_storage.value, rv_storage.name, m_warehouse.name AS warehouse_name, rv_storage.qtyonhand, rv_transaction.m_transaction_id, CASE WHEN rv_transaction.movementtype

我有以下代码:

SELECT 
    rv_storage.m_product_id AS n_product_id,
    rv_storage.value,
    rv_storage.name,
    m_warehouse.name AS warehouse_name,
    rv_storage.qtyonhand,
    rv_transaction.m_transaction_id,

    CASE WHEN rv_transaction.movementtype = 'V+' THEN movementdate
    ELSE NULL END AS last_in,

    CASE WHEN rv_transaction.movementtype = 'C-' THEN movementdate
    ELSE NULL END AS last_out,

    rv_transaction.movementagedays,

    CASE WHEN (movementagedays < -90) AND (movementagedays >= -180)  THEN qtyonhand
    ELSE NULL END AS more_than_90,

    CASE WHEN movementagedays < -180 THEN qtyonhand
    ELSE NULL END AS more_than_180
FROM
    adempiere.rv_storage
    INNER JOIN
    adempiere.rv_transaction ON
        rv_transaction.m_product_id = rv_storage.m_product_id 
        AND rv_transaction.movementagedays = (
            SELECT MAX(movementagedays) 
            FROM adempiere.rv_transaction 
            WHERE
                rv_transaction.m_product_id = rv_storage.m_product_id 
                AND rv_transaction.movementtype = 'C-'
                OR rv_transaction.movementtype = 'V+'
            )
    INNER JOIN
    adempiere.m_warehouse ON
        m_warehouse.m_warehouse_id = rv_storage.m_warehouse_id
WHERE rv_storage.m_product_id IN (
    SELECT m_product_id
    FROM adempiere.rv_transaction
    WHERE movementagedays < -90
    )
ORDER BY n_product_id;
结果如下表所示:

但是在每个表上都有超过100k行的实时数据的服务器上,速度太慢了。 有人能告诉我如何优化代码吗

谢谢

中的和非中的子查询优化得很差: MySQL将子查询作为外部查询中每一行的从属子查询执行。这是MySQL 5.5及更早版本中经常出现严重性能问题的原因。查询可能应该分别重写为联接或左外部联接。

where子句中的子查询是多余的。我认为您在内部联接子查询的where子句中缺少一个括号:

SELECT 
    rv_storage.m_product_id AS n_product_id,
    rv_storage.value,
    rv_storage.name,
    m_warehouse.name AS warehouse_name,
    rv_storage.qtyonhand,
    rv_transaction.m_transaction_id,

    CASE WHEN rv_transaction.movementtype = 'V+' THEN movementdate
    ELSE NULL END AS last_in,

    CASE WHEN rv_transaction.movementtype = 'C-' THEN movementdate
    ELSE NULL END AS last_out,

    rv_transaction.movementagedays,

    CASE WHEN (movementagedays < -90) AND (movementagedays >= -180)  THEN qtyonhand
    ELSE NULL END AS more_than_90,

    CASE WHEN movementagedays < -180 THEN qtyonhand
    ELSE NULL END AS more_than_180
FROM
    adempiere.rv_storage
    INNER JOIN
    adempiere.rv_transaction ON
        rv_transaction.m_product_id = rv_storage.m_product_id 
        AND rv_transaction.movementagedays = (
            SELECT MAX(movementagedays) 
            FROM adempiere.rv_transaction 
            WHERE
                rv_transaction.m_product_id = rv_storage.m_product_id 
                AND (rv_transaction.movementtype = 'C-'
                    OR rv_transaction.movementtype = 'V+')
            )
    INNER JOIN
    adempiere.m_warehouse ON
        m_warehouse.m_warehouse_id = rv_storage.m_warehouse_id
WHERE movementagedays < -90
ORDER BY n_product_id;

现在发布解释输出。

Marian没有使用MySQL,PostgreSQL的优化器在子选择方面比MySQL聪明得多。请使用解释分析发布执行计划,作为链接和表上的任何索引定义。另外,请检查一下:最后,您可能还需要考虑重新格式化查询以使其可读。我是新来的。。好的,我输入了你的代码,从35毫秒下降到6。。我不知道你是怎么做到的。。不管怎样,这里是你的解释:@MariánZekeŠedaj:你的执行计划不支持你对每张表上超过100k行的索赔。似乎大多数表都有大约20-80行。