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

ただし、ライブデータ(各テーブルに10万行以上)があるサーバーでは、速度が遅すぎます。誰かがコードを最適化する方法を教えてもらえますか?

ありがとうございました

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;

次に、Explain出力を投稿します。

于 2012-10-26T11:27:53.647 に答える
0

IN()およびNOT IN()サブクエリは最適化されていません 。MySQLは、外部クエリの各行の依存サブクエリとしてサブクエリを実行します。これは、MySQL5.5以前のバージョンで深刻なパフォーマンスの問題が発生することがよくあります。クエリは、おそらくそれぞれJOINまたはLEFTOUTERJOINとして書き直す必要があります。

于 2012-10-26T11:00:29.923 に答える