지난번에 인덱스 타는거 관련해서 /*+USE_CONCAT*/ 관련 처리가 안먹혀서 이런 저런 생각을 해보다가
답변 주셨던 어떤 분의 말씀으로 넘어오는 인자 구조를 좀 바꿔서 받으면 어떠냐고 하신 답글이 있어서요
프로그램에서 인자로 넘어오는 데이터가 p_param = 'A,B,C' 입니다.
이걸 IN 조건에 어떻게 넣을 수 없을까요?
SELECT
t.*
FROM TBL t
WHERE t.lot IN (
SELECT nvl2(p_param, trim(substr(wdata,instr(wdata, ',', 1, LEVEL) + 1,instr(wdata, ',', 1, LEVEL + 1) - instr(wdata, ',', 1, LEVEL) - 1))
, lh.lot) AS code_value
FROM
(SELECT ',' || p_param || ',' AS wdata FROM DUAL)
CONNECT BY LEVEL <= length(wdata) - length(REPLACE(wdata, ',')) - 1
)
이런 구조로 되어 있습니다. 저 IN 조건 우측은 'A,B,C' 의 형태를
A
B
C
형태의 행으로 바꾸어주는 것이고 그걸 다시 IN 조건으로 되는건데요
저부분을
SELECT
t.*
FROM TBL t
WHERE t.lot IN ('A','B','C')
고정으로 박아보면 무지 빠릅니다. 그런데 저 CONNECT BY를 넣으니 무진장 한없이 느려집니다.
그래서 지난번 답변에서 처럼 C# 프로그램에서 넘어오는 A,B,C 형태를 'A','B','C' 형태로 미리 파싱한 것처럼 바꾸서어 IN에 대입하는 식으로 해볼려는데요
동적 쿼리 말고 방법이 있을까요? 동적쿼리 사용이 여기서는 금지 되어 있습니다..
화면의 어떤 조건 항목들에 따라 달라져야 되어서요
REGEXP_SUB()를 사용해서 아래와 같이 해봤는데도
안되네요
p_param = ''A,B,C';
SELECT
/*+ USE_CONCAT */
t.lot
FROM TBL t
WHERE 1=1
AND
(
(p_param IS NOT NULL)
AND t.lot IN (
SELECT
DECODE(REGEXP_SUBSTR(p_param, '[^,]+', 1, LEVEL), NULL, t.lot, REGEXP_SUBSTR(p_param, '[^,]+', 1, LEVEL))
FROM DUAL
CONNECT BY REGEXP_SUBSTR(p_param, '[^,]+', 1, LEVEL) IS NOT NULL
)
)
OR
(
(p_param IS NULL)
AND t.from_dt >= p_from AND t.to_dt < p_to
)
p_param에 값이 있을경우는 p_param의 A,B,C 형태로 된 것을 IN 조건으로 걸어 조회되어야 되고
p_param의 값이 없다면 기간별로 p_from과 p_to의 값을 이용하여 범위검색을 해야 됩니다.
조건에 따라서 인덱스가 달라져야 되는데 현재 저 IN 부분에서 막히네요