2009-04-27 6 views
0

요구 사항 변경으로 인해 복잡한 SQL where 절이 생겼습니다. 네 가지 기본 사례 집합이 있으며 각각 다른 요소의 다른 조합이 있습니다. 네 가지 경우를 where 절의 별도 분기로 사용하고 각 분기마다 중복 기준을 반복하는 것이 더 읽기 쉽습니다. 그러나 데이터베이스 엔진이 얼마나 잘 최적화 할 것인지 잘 모릅니다.복잡한 SQL where 절 : 논리를 계수 할 것인지 여부

다음은 중복 형식의 표현입니다. 나는 실제 기준을 문자로 바꿨다. A는 네 가지 형태로 제공되는 "분기 (branching)"기준입니다. 별도로 명시하지 않는 한 모든 표현식은 field='value' 형식입니다.

A1 AND B AND C AND D 
OR A2 AND B AND C AND D AND E AND F1 AND G 
OR A3 AND A3a AND B AND C AND D AND E AND F1 AND G 
OR A4 AND B AND C AND D AND F2 

A4의 A는 모두 field in ('value1','value2')입니다. D는 field > 'value'입니다. G는 field not in (subquery)의 형식입니다.

다음은 최소한의 중복 양식을 고려한 표현입니다.

B AND C AND D AND (
    A1 
    OR (
     E AND F1 AND G AND (
      A2 
      OR (A3 AND A3a) 
     ) 
    ) 
    OR (A4 AND F2) 

내 질문은 내가 가장 간단한 (이상 중복)에이 표현 논리적 양식을 고려하거나 더 중복뿐만 아니라 더 읽을 수있는 형태의에서 그것을 유지하기 위해 확인을인지해야하는지 여부입니다. 대상 데이터베이스는 Sybase이지만 일반적으로 RDMBS에 대한 대답을 알고 싶습니다.

답변

2

RDBMS 세계에서 나는 중복성을별로 신경 쓰지 않겠지 만 효율성은 여기에서 더 중요합니다. 귀하의 경우에는

,이 같은 최고 조건으로 A 년대를 사용하는 모든 네 개의 쿼리를 UNION 것 :

SELECT * 
FROM mytable 
WHERE A1 AND B AND C 
UNION 
SELECT * 
FROM mytable 
WHERE A2 AND B AND C AND D AND E AND F1 AND G 
… 

나는 그러나 모두 이상 7년에 대한 Sybase에 보이지 않았다 대문자 인 RDBMSUNIONOR보다 효율적입니다.

Oracle에 silimar 문제로 접근 내 블로그에서이 문서를 참조하십시오

이 문서의 UNION의 효율적 사용 MySQL :

  • Selecting friends은 : UNION의 효율성 나는이 방법이 너무 Sybase 잘 작동합니다 생각 MySQL

OR 중 하나에 비교했다.

는 또한 UNION의 혜택을 당신의 조건에 사용되는 컬럼에 인덱스를 생성해야

업데이트 :

조건 G 하위 쿼리이기 때문에, 아마 그것이 HASH JOIN을 필요로 발생할 수 있습니다 빨리 수행 할 수 있습니다.

SELECT * 
FROM (
     SELECT * 
     FROM foo 
     WHERE condition_set_1 
     UNION 
     SELECT * 
     FROM foo 
     WHERE condition_set_2_but_no_g 
     … 
     ) q 
WHERE G 

이 더 판단을하기 위해서는 훨씬 더 좋을 것이다 : HASH JOIN는 가능한 하나의 FULLSCAN 모든 값을 필터링하고 HASH JOIN A가 수행하는 것이 더있을 수 있습니다 이유, 모든 필터링되지 않은 값에 대한 전체 검사를 필요 정말 쿼리 자체를 참조하십시오.

+0

좋습니다. 조건 G가 하위 쿼리를 사용한다는 사실은 UNION 접근법의 효율성이 떨어지게 될까요 (이론적으로 두 개의 SELECT에서 발생하기 때문에), 아니면 데이터베이스 엔진이 이러한 유형의 것을 최적화합니까? –

+0

G의 경우 판단을 내리기 위해 쿼리 자체를 보는 것이 필요합니다. 하위 쿼리가 복잡하면 G는 분리 된 UNION 쿼리에 사용 된 인덱스의 모든 이점을 제거 할 수 있습니다. 어쩌면 전체 테이블 스캔이 더 나을 수도 있습니다. – Quassnoi

+0

하위 쿼리 논리는 간단하지만 테이블이 큽니다. 하위 쿼리는 인덱싱 된 필드에서 선택하므로 너무 나쁘지 않을 수 있습니다. 나는이 특별한 경우가 내가 여러 가지 방법으로 시도해야하고 가장 잘 작동하는 것을 볼 수있는 곳이라고 생각한다. –

0

리팩터링합니다. 결국 중복 된 논리로 인해 문제가 발생할 수 있습니다. 두 번째 예제는 이해하는 데 몇 초가 더 걸릴 수도 있지만 큰 사안에서는 where 절 전체를 빠르게 살펴보고 무엇에 영향을 미치는지 판단하기 시작할 때 진행되는 것을 더 쉽게 볼 수 있습니다.

2

M $ SQL Server에서이 문제를 공격 한 경우 원하는 방식으로 작성하고 쿼리 실행 계획을 살펴 보겠습니다. 만약 (a)가 느리게 달렸고 (b) 나쁜 실행 계획을 가지고 있다면, 나는 리팩터링하고 문서화 할 것입니다. 옵티마이 저가 쿼리를 실행하는 방법을보기 위해 Sybase의 메커니즘이 확실하지 않습니다.

+0

게시물 주셔서 감사합니다. Sybase에서는 쿼리를 실행하기 전에 SET SHOWPLAN ON을 실행할 수 있으며 자세한 내용을 보여줍니다 (텍스트 기반 형식이나 SQL Server와 같은 그래픽 표현이 아님) –