Running explain plan on this query I am getting Full table Access.
Two tables used are:
user_role: 803507 rows
cmp_role: 27 rows
Query:
SELECT
r.user_id, r.role_id, r.participant_code, MAX(status_id)
FROM
user_role r,
cmp_role c
WHERE
r.role_id = c.role_id
AND r.participant_code IS NOT NULL
AND c.group_id = 3
GROUP BY
r.user_id, r.role_id, r.participant_code
HAVING MAX(status_id) IN (SELECT b.status_id FROM USER_ROLE b
WHERE (b.ACTIVE = 1 OR ( b.ACTIVE IN ( 0,3 )
AND SYSDATE BETWEEN b.effective_from_date AND b.effective_to_date
))
)
How can I better write this query so that it returns results in a decent time. Following are the indexes:
idx 1 = role_id
idx 2 = last_updt_user_id
idx 3 = actv_id, participant_code, effective_from_Date, effective_to_date
idx 4 = user_id, role_id, effective_from_Date, effective_to_date
idx 5 = participant_code, user_id, roke_id, actv_cd
Explain plan:
Q_PLAN
--------------------------------------------------------------------------------
SELECT STATEMENT
FILTER
HASH GROUP BY
HASH JOIN
TABLE ACCESS BY INDEX ROWID ROLE
INDEX RANGE SCAN N_ROLE_IDX2
TABLE ACCESS FULL USER_ROLE
TABLE ACCESS BY INDEX ROWID USER_ROLE
INDEX UNIQUE SCAN U_USER_ROLE_IDX1
FILTER
HASH GROUP BY
HASH JOIN
TABLE ACCESS BY INDEX ROWID ROLE
INDEX RANGE SCAN N_ROLE_IDX2
TABLE ACCESS FULL USER_ROLE
TABLE ACCESS BY INDEX ROWID USER_ROLE
INDEX UNIQUE SCAN U_USER_ROLE_IDX1
I do not have enough priveleges to run stats on the table
Tried the following changes but it shaves off 1 or 2 seconds only:
WITH CTE AS (SELECT b.status_id FROM USER_ROLE b
WHERE (b.ACTIVE = 1 OR ( b.ACTIVE IN ( 0,3 )
AND SYSDATE BETWEEN b.effective_from_date AND b.effective_to_date
))
)
SELECT
r.user_id, r.role_id, r.participant_code, MAX(status_id)
FROM
user_role r,
cmp_role c
WHERE
r.role_id = c.role_id
AND r.participant_code IS NOT NULL
AND c.group_id = 3
GROUP BY
r.user_id, r.role_id, r.participant_code
HAVING MAX(status_id) IN (select * from CTE)