2015-02-02 4 views
0

아무 것도 이해할 수 없습니다. Oracle 11g db에는 많은 데이터와 테이블이 있습니다. 일부 테이블에 가입하고 결과를 출력하고 싶습니다. 좋아, 단지 썼다 :SQL 쿼리 최적화 도구

SELECT * 
FROM Table1 
LEFT JOIN Table2 ON Table2.Table1_Id = Table1.Table1_Id 
WHERE Table2.Column1=1 
  • 매우 간단하지만 너무 느린. 좋아요, Table2는 Table3과 연결되어 있습니다. 이 테이블에는 Table1과 일반적으로 연결되어 있음을 알려주는 몇 가지 플래그가 있습니다. 나는 다음 코드를 작성 :

    SELECT * 
    FROM Table1 
    LEFT JOIN Table2 ON Table2.Table1_Id = Table1.Table1_Id 
    LEFT JOIN Table3 ON Table3.Table3_Id = Table2_Table3_Id 
    WHERE 
    Table3.ColumnWithFlag LIKE '%some id info about Table1%' 
    AND Table2.Column1=1 
    

를이 쿼리는 빠른 첫 번째 쿼리 후 저렴한 비용을 가지고. 왜, 이해가 안되니? 내 쿼리에서 3 테이블을 사용하고 더 빨리 작업 한 다음 2 테이블 (행 개수는 동일하고 데이터는 동일)로 쿼리합니다.

+2

OUTER JOIN 인 경우 외부 테이블의 조건을 WHERE 절에 넣지 말고 대신 ON 절에 넣으십시오. (그렇지 않은 경우 수행되는 정규 내부 조인입니다.) – jarlh

+1

@jarlh, 외부 조인시 ON 절과 Where 절의 조건이 매우 다릅니다. 잘못된 결과가 나오지 않도록 조심해야합니다. 어디에서 행을 걸러 낼 것인가? ON에서는 그렇지 않다. –

+1

두 번째 질의에 추가 된 조건이있다. 'Table3.ColumnWithFlag LIKE'대부분의 데이터를 필터한다고 가정하는 Table1 % '에 대한 일부 ID 정보 귀하의 결과 세트,하지만 여전히 텍스트 파싱이고 'LIKE'는이 작업을 수행하는 데 매우 효율적이지 않습니다. 그러나 이것은 추측 일뿐입니다. 두 쿼리의 실행 계획을 비교하여 "병목 현상"이 어디에 있는지 확인하는 것이 가장 좋습니다. –

답변

2

먼저 몇 가지 기본 사항이 있습니다. WHERE 절은 어쨌든 INNER JOIN로 바뀝니다 때문에

SELECT * 
FROM Table1 t1 LEFT JOIN 
    Table2 t2 
    ON t2.Table1_Id = t1.Table1_Id 
WHERE t2.Column1 = 1; 

LEFT JOIN는 불필요 :이 첫 번째 쿼리입니다. 일치하는 항목이 없으면 t2.Column1NULL이고 필터가 제거됩니다.

나는이 성능 문제를 볼 수있는 방법 중 적어도 하나를 상상할 수 있습니다. 기본적으로 Table2Table1_Id에 대한 색인이 없지만 Table3_Id에 대한 색인이있는 경우

이 경우 첫 번째 쿼리 계획은 Table2 (아마도 Column1의 인덱스를 사용)을 스캔 한 다음 데이터베이스 마법을 수행해야합니다. 아마도 테이블에서 해시 조인을 수행해야합니다.

두 번째 쿼리는 사용 가능한 인덱스를 사용하여 Table2Table3을 결합합니다. 이것은 (아마) Table2보다 훨씬 작을 것입니다. 데이터베이스 매직은 매우 큰 테이블의 전체 테이블 스캔을 허용하지 않습니다.

가능한 시나리오 중 하나입니다. 실제적인 방법은 쿼리 실행 계획을보고 무엇이 다른지 확인하는 것입니다.

+0

같은 생각이지만 "Table2에서 필요없는 행을 제거해야한다"는 Oracle의 이해 방법을 이해할 수 없습니다. – Mixim

+0

@Mixim. . . 쿼리에서 행에 액세스하는 방법에 대한 질문입니다. 첫 번째 쿼리는 오라클에게 테이블에있는 모든 행을 검색하여 액세스 할 수있는 유일한 방법을 제공합니다. 두 번째는 오라클이 인덱스를 사용하여 다른 액세스 방법을 제공 할 수 있습니다. –