需要帮助调整查询 - 使用连接字段的左连接效率不高

时间:2014-06-15 19:29:32

标签: sql oracle query-optimization

我编写了一个查询,其中我从群体中过滤出记录,其中嵌套查询中的2个字段的值等于表中的2个对应字段。我正在尝试使用2个关键字段的串联作为查找。

虽然这确实让我得到了我正在寻找的结果,但是这个方法似乎非常低效,因为查询大约需要60秒才能返回结果(CRM.ASSET_PLUS表有超过10M的记录)。假设我无法过滤掉任何内容,并且没有在CRM.ASSET_PLUS中创建自定义字段,并且已经连接了这两个字段。

我有更好的方法吗?

SELECT DISTINCT A.ACCOUNT_NUMBER
  FROM (SELECT C.ACCOUNT_NUMBER,
               A.LOCATION_ACCOUNT_ID || A.PRODUCT_ID AS LOOKUP
          FROM CRM.ASSET_PLUS A,
               CRM.PROD_INT B,
               CRM.ACCOUNT C,
               CRM.ACCOUNT D
         WHERE A.PRODUCT_ID = B.ROW_ID
           AND A.LOCATION_ACCOUNT_ID = C.ACCOUNT_ID
           AND C.PARENT_ID = D.ACCOUNT_ID
           AND D.ACCOUNT_NUMBER = '00750333'
       ) A
   LEFT JOIN (SELECT A.LOCATION_ACCT_ID || A.PRODUCT_ID AS LOOKUP
                FROM ORDER_FORM_PRODUCTS A
               WHERE A.AGREEMENT_NUM = '00750333_JUN2014'
             ) B
     ON A.LOOKUP = B.LOOKUP
  WHERE B.LOOKUP IS NULL;

1 个答案:

答案 0 :(得分:3)

而不是连接尝试加入多个字段

SELECT DISTINCT
    A.ACCOUNT_NUMBER
FROM 
    CRM.ASSET_PLUS A,
    CRM.PROD_INT B,
    CRM.ACCOUNT C,
    CRM.ACCOUNT D
LEFT JOIN ORDER_FORM_PRODUCTS E 
    ON (E.LOCATION_ACCOUNT_ID = A.LOCATION_ACCOUNT_ID
       OR (E.LOCATION_ACCOUNT_ID IS NULL AND A.LOCATION_ACCOUNT_ID IS NULL))
    AND (E.PRODUCT_ID = A.PRODUCT_ID 
        OR (E.PRODUCT_ID IS NULL AND A.PRODUCT_ID IS NULL))
    AND E.AGREEMENT_NUM = '00750333_JUN2014'
WHERE 
    A.PRODUCT_ID = B.ROW_ID 
    AND A.LOCATION_ACCOUNT_ID = C.ACCOUNT_ID
    AND C.PARENT_ID = D.ACCOUNT_ID
    AND D.ACCOUNT_NUMBER = '00750333'
    AND E.LOCATION_ACCOUNT_ID IS NULL
    AND E.PRODUCT_ID IS NULL

为清楚起见,我建议您明确地使用联接

SELECT DISTINCT
    A.ACCOUNT_NUMBER
FROM 
    CRM.ASSET_PLUS A
    JOIN CRM.PROD_INT B ON A.PRODUCT_ID = B.ROW_ID
    JOIN CRM.ACCOUNT C ON A.LOCATION_ACCOUNT_ID = C.ACCOUNT_ID
    JOIN CRM.ACCOUNT D ON C.PARENT_ID = D.ACCOUNT_ID
        AND D.ACCOUNT_NUMBER = '00750333'
    LEFT JOIN ORDER_FORM_PRODUCTS E 
       ON (E.LOCATION_ACCOUNT_ID = A.LOCATION_ACCOUNT_ID
         OR (E.LOCATION_ACCOUNT_ID IS NULL AND A.LOCATION_ACCOUNT_ID IS NULL))
       AND (E.PRODUCT_ID = A.PRODUCT_ID 
         OR (E.PRODUCT_ID IS NULL AND A.PRODUCT_ID IS NULL))
       AND E.AGREEMENT_NUM = '00750333_JUN2014'
WHERE 
    E.LOCATION_ACCOUNT_ID IS NULL
    AND E.PRODUCT_ID IS NULL