0

我有这个代码:

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;

结果如下表:

表 http://img9.imageshack.us/img9/4506/table3n.png

但是在具有实时数据的服务器上(每个表上 100k+ 行)它太慢了。有人可以告诉我如何优化代码吗?

谢谢你

4

2 回答 2

1

子句中的子查询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;

现在发布解释输出。

于 2012-10-26T11:27:53.647 回答
0

IN() 和 NOT IN() 子查询的优化很差: MySQL 将子查询作为外部查询中每一行的依赖子查询执行。这是 MySQL 5.5 和更早版本中严重性能问题的常见原因。查询可能应该分别重写为 JOIN 或 LEFT OUTER JOIN。

于 2012-10-26T11:00:29.923 回答