2013-12-02 2 views
3

Firebird는 조건을 실행하는 방법을 모릅니다. 아니면 그것이 내가 생각하는 것입니다.조건부 절이 끔찍한 성능을 초래합니다. Firebird

첫 번째 쿼리는 15ms 후에 값을 반환합니다.

SELECT DISTINCT 
      A.MANID, 
      A.DISNO, 
      A.DISID 
      FROM 
      TABLEB B 
      INNER JOIN TABLEA A ON (A.ITEM_ID = B.ITEM_ID) 
      WHERE 
      (
       (POSITION('%' IN :ISEARCH) = 0 AND B.CATID = :ISEARCH) 
      ) 

이 두 번째 쿼리는 40 초 이상 소요되며 모두 OR 조건입니다.

SELECT DISTINCT 
      A.MANID, 
      A.DISNO, 
      A.DISID 
      FROM 
      TABLEB B 
      INNER JOIN TABLEA A ON (A.ITEM_ID = B.ITEM_ID) 
      WHERE 
      (
       (POSITION('%' IN :ISEARCH) = 0 AND B.CATID = :ISEARCH) OR 
       POSITION('%' IN :ISEARCH) <> 0 
      ) 

어떻게 이런 종류의 상황에서 행동하라고 말할 수 있습니까?

+1

각각에 대해 계획은 어떻게됩니까? 그것은 무슨 일이 일어나고 있는지에 대한 가장 큰 단서가 될 것입니다. – nater

+0

첫 번째 쿼리는 'CATID'에 인덱스가있는 경우 최적화 될 수 있지만 두 번째 쿼리는 자연 스캔입니다. 'UNION ALL'을 사용하여 두 개의 쿼리를 시도해보고 어떻게 수행하는지 볼 수 있습니다. –

+0

예, Firebird가 두 번째 쿼리를 처리 할 수없는 것 같습니다. OR 조건은 즉시 인덱스를 제거하고 계획을 강제 실행하더라도 전체 테이블 스캔을 수행합니다. 여러 가지 쿼리를 사용하여 솔루션에 접근해야했습니다. 이에 답변 해 주셔서 감사합니다. – user1791567

답변

0

A는 억지 비트와 나는 파이어 버드 익숙하지 않아요하지만이 특별한 경우에 나는

(
    (POSITION('%' IN :ISEARCH) = 0 AND B.CATID = :ISEARCH) OR 
    POSITION('%' IN :ISEARCH) <> 0 
) 

더 적합 할 수 있습니다

(
    (POSITION('%' IN :ISEARCH) <> 0 OR B.CATID = :ISEARCH) 
) 

처럼 쓸 시도하는 것이 좋습니다 것 쿼리 최적화 프로그램에?

최악의 경우 당신이 다시 함께 하나가 POSITION('%' IN :ISEARCH) <> 0을 처리 UNION ALL이 별도의 쿼리로 문을 분할을 시도 할 수 있습니다 ... 그것은 여전히 ​​OR와 RDBMS에 많은 OR의 마음에 들지입니다하지만 해볼만 한 가치 다른 하나는 B.CATID = :ISEARCH입니다. 이 접근 방식의 문제는 필터링 된 항목을 두 번 다시 필터링해야 할 수 있습니다. (일명 : 새로운 웜 깡통 ...)

+0

제안 해 주셔서 감사합니다. Mark R.은 Firebird의 WHERE 절에서이 조건을 사용하지 말아야하는 이유를 알려주었습니다. 또한 우리는 v.2.1이 테이블에 가져 오는 몇 가지 개선점이 부족한 v.2.1을 사용하고 있습니다. 다시 한번 감사드립니다. – user1791567