2012-10-26 55 views
0

我有這樣的代碼:PostgreSQL的代碼optimalization

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; 

導致如下表:

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

但隨着實時數據(在每張桌子上100K +行)在服務器上實在是太慢。 有人可以告訴我如何優化代碼?

謝謝

+2

請後(使用說明分析)執行計劃,爲紐帶,以http://explain.depesz.com,你必須在表上的任何索引定義。還請看看這個:http://wiki.postgresql.org/wiki/SlowQueryQuestions(最後你可能還想考慮重新格式化你的查詢以使其可讀)。 –

回答

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; 

現在發佈解釋輸出。

+0

UFFF ..即時通訊新本..好了,所以我輸入驗證碼,並從35MS它去到6 ..我不知道你是怎麼做的吧..反正這裏是你的解釋:http://explain.depesz.com/s/inq –

+0

@MariánZekeŠedaj:你的執行計劃不支持您的要求「* 100K +每個桌子上的行*「。看起來大多數桌子都有20-80行左右的東西。 –

0

IN()而不是在()子查詢優化很差: MySQL的執行子查詢爲外部查詢的每一行相關子查詢。這是MySQL 5.5及更早版本中嚴重性能問題的常見原因。查詢可能應該分別重寫爲JOIN或LEFT OUTER JOIN。

+1

瑪麗安是*不*使用MySQL和PostgreSQL的的優化是一個** **很多聰明的,當涉及到子選擇比MySQL –