A라는 테이블에 데이터가 꽤 많이 있습니다.
여기에서 item값이 없다면 기간에 대해서 데이터를 뽑아오고, item값이 존재한다면 해당 item에 대해서 조회해 오려고 합니다. 인덱스가 분리 되어야되는데요
SELECT
*
FROM A
WHERE 1=1
AND
(
(
p_item IS NULL
AND create_date >= p_from AND create_date < p_to
)
OR
(
p_item IS NOT NULL
AND item = p_item
)
)
그런데 여기서 문제가 되는게 있는데요 p_item이 1개면 저렇게 = 로 하면 데이터가 빨리나오는데요
그게 아니고 파라미터로 넘어온 p_item이 , 기반으로 된 것이라면
p_item = '거위,오리,강아지,닭'
이런식이면 , 단위로 구분하여 4개의 item이 조회되어야 되는데요
SELECT
*
FROM A
WHERE 1=1
AND
(
(
p_item IS NULL
AND create_date >= p_from AND create_date < p_to
)
OR
(
p_item IS NOT NULL
AND item IN (
SELECT
REGEXP_SUBSTR(p_item, '[^,]+', 1, LEVEL) TXT
FROM DUAL
CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(p_item, '[^,]+',''))+1
)
)
)
이렇게 REGEXP_STR()을 사용하여 , 구분자 단위로 행을 만들어서 item이 있는지 IN 절을 썼는데요
너무 느립니다....
방법이 없을까요? 인덱스 구분할려고 하다가 여기까지 와버렸네요 ㅠㅠ 하나 해결할 듯 싶으면 또 하나가 문제 되고
여드름 같이 ㅠㅠ
/*+ USE_CONCAT */를 SELECT 절에 썼는데요
SELECT
/*+ USE_CONCAT */ t.*
FROM A t
WHERE 1=1
AND
(
(
p_item IS NULL
AND t.create_date >= p_from AND t.create_date < p_to
)
OR
(
p_item IS NOT NULL
AND t.item IN (
SELECT
REGEXP_SUBSTR(p_item, '[^,]+', 1, LEVEL) TXT
FROM DUAL
CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(p_item, '[^,]+',''))+1
)
)
)
역시나 p_item이 존재할 시에 조회하면 느립니다. 이래 저래 해보고 있는데요 마농님~
저기 조건에
AND t.item IN (
SELECT
REGEXP_SUBSTR(p_item, '[^,]+', 1, LEVEL) TXT
FROM DUAL
CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(p_item, '[^,]+',''))+1
)
이부분을 하드코딩으로
AND t.item IN ('거위', '오리', '강아지', '닭')
이렇게 하면 바로 조회가 되어버립니다.
그런데
AND t.item IN (
SELECT
REGEXP_SUBSTR('거위,오리,강아지,닭', '[^,]+', 1, LEVEL) TXT
FROM DUAL
CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE('거위,오리,강아지,닭', '[^,]+',''))+1
)
이렇게 하면 너무 오래걸려버립니다.
안에
SELECT
REGEXP_SUBSTR('거위,오리,강아지,닭', '[^,]+', 1, LEVEL) TXT
FROM DUAL
CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE('거위,오리,강아지,닭', '[^,]+',''))+1
이부분만 따로 조회하면 또 빨리 나오구요
A 테이블은 엄청 데이터가 많습니다
Index는 item, create_date 가 인덱스 걸려 있습니다