3

I have written the below query which has many 'AND' operators, i would like to know how to optimize the performance of the below query [can i remove some of the 'AND' Operators]

    SELECT I.date,
              K.somcolumn,
              L.somcolumn,
              D.somcolumn
         FROM Table1 I,
              Table2 K,
              Table3 L,
              Table4 D
        WHERE I._ID = K._ID
              AND K.ID = L._ID
              AND L._ID = I._ID
              AND I._CODE = L._CODE
              AND K.ID = D._ID(+)
              AND L._ID IN ( SELECT _id
                                       FROM I
                                      WHERE UPPER (someflag) = 'TRUE'
                                   GROUP BY _id
                                     HAVING COUNT (*) > 1)
              AND L._ID IN ( SELECT _id
                                       FROM I
                                      WHERE UPPER (code) = 'OPEN'
                                   GROUP BY _id
                                     HAVING COUNT (*) > 1)
     ORDER BY I._ID, I._CODE;
2
  • If there are few rows returned you could try doing the count from table I as a new returned column using a scalar subquery. You could also try using a WITH clause building a temporary table from table I. Just ideas. I am unable to produce an answer as I cannot verify my ideas. Commented Dec 30, 2014 at 16:09
  • Also it may be significantly faster using EXISTS than IN as index can be used. EXISTS ( SELECT NULL FROM I WHERE L._id=_id AND UPPER(code) = 'OPEN' GROUP BY _id HAVING COUNT (*) > 1). As index may be used for _id code and someflag are candidates for bitmap index perhaps. Commented Dec 30, 2014 at 16:16

2 Answers 2

2

You can't combine any of the conditions as far as I can tell, but you can improve the query and reduce the number of AND operators by using standard JOIN syntax:

SELECT I.date,
  K.somcolumn,
  L.somcolumn,
  D.somcolumn
FROM Table1 I
INNER JOIN Table2 K ON I._ID = K._ID
INNER JOIN Table3 L ON K.ID = L._ID
LEFT JOIN Table4 D ON K.ID = D._ID
WHERE L._ID IN ( SELECT _id
   FROM I
   WHERE UPPER (someflag) = 'TRUE'
   GROUP BY _id
   HAVING COUNT (*) > 1)
 AND L._ID IN ( SELECT _id
   FROM I
   WHERE UPPER (code) = 'OPEN'
   GROUP BY _id
   HAVING COUNT (*) > 1)
ORDER BY I._ID, I._CODE;

With that as a basis, you may get an optimization boost if you join to the subquery conditions rather than using correlated subqueries. No guarantees, but something like this may help:

SELECT I.date,
  K.somcolumn,
  L.somcolumn,
  D.somcolumn
FROM Table1 I
INNER JOIN Table2 K ON I._ID = K._ID
INNER JOIN Table3 L ON K.ID = L._ID
LEFT JOIN Table4 D ON K.ID = D._ID
INNER JOIN (
    SELECT _id
    FROM I
    WHERE UPPER (someflag) = 'TRUE'
    GROUP BY _id
    HAVING COUNT (*) > 1
  ) someflagtrue ON L._ID = someflagtrue._id
INNER JOIN (
    SELECT _id
     FROM I
     WHERE UPPER (code) = 'OPEN'
     GROUP BY _id
     HAVING COUNT (*) > 1
  ) codeopen ON L._ID = codeopen._id
ORDER BY I._ID, I._CODE;
Sign up to request clarification or add additional context in comments.

Comments

0

You can replace the two subqueries with one.

Old subqueries:

  SELECT _id
    FROM I
   WHERE UPPER (someflag) = 'TRUE'
GROUP BY _id
  HAVING COUNT (*) > 1)

  SELECT _id
    FROM I
   WHERE UPPER (code) = 'OPEN'
GROUP BY _id
  HAVING COUNT (*) > 1)

New subquery:

SELECT _ID
  FROM I
 GROUP BY _ID
HAVING COUNT(CASE WHEN UPPER(SOMEFLAG) = 'TRUE' THEN 1 ELSE 0 END) > 0
   AND COUNT(CASE WHEN UPPER(CODE) = 'OPEN' THEN 1 ELSE 0 END) > 0

In most cases this should be at least a little faster as it may reduce the number of full table scans and joins. But it's difficult to tell if it will be faster on your system since there are so many possible choices for the optimizer to make.

After cleaning up the query the next step for performance tuning is to generate an explain plan. Run explain plan for select ...; and then run select * from table(dbms_xplan.display); That will show you how the query is executed, which may give you a hint at what is slow and what can be improved. Add the full output of th explain plan to your question if you need more help. It may also help to add information about the number of rows in the relevant tables, how many rows are returned, and what are the indexes.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.