data 는 30만건 정도 됩니다.
기존에는 검색 필드 를 단일로 선택해서 검색 했었습니다.
요청이 들어와서 통합 검색을 하다보니 저렇게 or 구문이 많습니다.
검색 하면 6초 정도 걸리는데요.
p_idx 는 PRIMARY KEY CLUSTERED 로 잡혀 있습니다.
replace 처리를 뻬면 3초 가 줄어 들긴 하는데요.
띄워 쓰기 를 해도 검색이 되게 해 달라는 요청이 있어서 저렇게 공백 처리를 했습니다.
좀더 빠르게 하고 싶습니다.
select top 100 a.p_tci_no, b.addr1 as cart, v_key --많아서 일부만 표시 했습니다.
from product a inner join product_pack b on a.p_tci_no = b.p_tci_no
where a.p_idx>0 and b.p_idx>0
and
(
Replace(a.p_tci_no,' ','') = 'ab' or
Replace(a.p_product,' ','') like '%검색어%' or
Replace(a.p_casno,' ','') = 'ab' or
Replace(a.p_elements,' ','') like '%검색어%' or
Replace(a.p_tci_no,' ','') = 'ab' or
Replace(a.pdongil1_,' ','') like '%검색어%' or
Replace(a.p_dongil2,' ','') like '%검색어%' or
Replace(a.p_dongil3,' ','') like '%검색어%' or
Replace(a.p_dongil4,' ','') like '%검색어%' or
Replace(a.p_dongil5,' ','') like '%검색어%' or
Replace(a.p_dongil6,' ','') like '%검색어%' or
Replace(a.p_dongil7,' ','') like '%검색어%'
)
and a.p_idx not in (
select top 0 a.p_idx from product a inner join product_pack b on a.p_tci_no = b.p_tci_no where a.p_idx>0
and b.p_idx>0 and
(
Replace(a.p_tci_no,' ','') = 'ab' or
Replace(a.p_product,' ','') like '%검색어%' or
Replace(a.p_casno,' ','') = 'ab' or
Replace(a.p_elements,' ','') like '%검색어%' or
Replace(a.p_tci_no,' ','') = 'ab' or
Replace(a.p_dongil1,' ','') like '%검색어%' or
Replace(a.p_dongil2,' ','') like '%검색어%' or
Replace(a.p_dongil3,' ','') like '%검색어%' or
Replace(a.p_dongil4,' ','') like '%검색어%' or
Replace(a.p_dongil5,' ','') like '%검색어%' or
Replace(a.p_dongil6,' ','') like '%검색어%' or
Replace(a.p_dongil7,' ','') like '%검색어%'
)
order by A.p_idx desc )
order by A.p_idx desc
Comment 6
-
군고구마
2013.12.08 20:52
-
죠리퐁
2013.12.09 11:56
실행 계획 첨부해서 올렸습니다.
한 번 봐주세요.
-
catchv
2013.12.09 10:05
WHERE 조건에서 테이블의 컬럼을 가공하면 테이블 스캔을 할 수 밖에 없습니다.(Replace(a.p_tci_no,' ','') 같은)
NOT IN 또한 스캔을 발생시키는 주요 원인이 될 수 있습니다. 쿼리만 보고 어떻게 고치시라고 이야기 하기는 힘들지만
1. WHERE 조건에서 테이블의 컬럼을 최대한 가공하지 않는다. ( 고민해 보시면 어쩔수 없는 경우 이외에는 변경이 대부분 가능합니다.)
2. NOT IN 제거 - 가능하다면 IN의 조건으로 변경하거나 아니면 Outer join으로 대체해서 비교를 해보세요. 컬럼이 많지 않을 경우 Outer join의 성능이 훨씬 빠른 경우가 많습니다.
-
죠리퐁
2013.12.09 11:57
outer join 으로 한 번 변경 해보겠습니다.
감사 합니다.
-
군고구마
2013.12.09 14:19
catchv님이 매우 설명을 잘해주셔서 ^^ 약간 저도 몇가지 추가적으로 말씀드리자면
Replace를 "검색어"에 적용 시키는것이 좋을 듯합니다.
그리고 질문자 님의 쿼리를 보고 실행계획을 보니 원체 지금 양이 많은거 같은데요.
이럴 경우 날짜로 검색을 추가하여 작은 양으로 줄이는것도 방법이라고 생각됩니다.
그리고 보면 order by A.p_idx desc )
order by A.p_idx desc 가 2번인데요.
구지 2번을 해야 할 필요가 있나요?
그 위에 order by 는 구지 필요없다고 생각됩니다.
order by는 상당히 비용을 많이 잡아 먹습니다 ^^
-
죠리퐁
2013.12.10 09:56
아레 minsouk 댓글 이 주된 내용인데
제가 질문을 제대로 못했습니다.order by 를 두번 한것은 페이징 때문에 그렇습니다.
minsouk 님이 정확이 짚어 주셨네요.
페이징을 하고 있구요.
검색어 값도 replace 처리 했습니다.
data를 replace 가공 하지 않으면 웹단에서 가공 하더라도 조건이 맞지 않으니 검색이 되지 않을 것 같은데요.
실행계획을 첨부해서 올려주시는게 더 좋을 듯 합니다.