programing

UNION with WHERE 조항

showcode 2023. 3. 11. 09:39
반응형

UNION with WHERE 조항

는 ★★★★★★★★★★★★★★★★★★★★★★★★」UNIONOracle ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」 다 '먹다'가 요.WHERE절을 클릭합니다.포먼 the the the the the 를 하면 에 차이가 있나요?WHERE 후에UNION과 "" 실행"의 비교UNION 후에WHERE조??

예를 들어 다음과 같습니다.

SELECT colA, colB FROM tableA WHERE colA > 1
UNION
SELECT colA, colB FROM tableB WHERE colA > 1

비교:

SELECT * 
  FROM (SELECT colA, colB FROM tableA
        UNION
        SELECT colA, colB FROM tableB) 
 WHERE colA > 1

두 번째 경우 퍼포먼스에 영향을 미치는 두 테이블 모두에서 풀 테이블스캔을 수행합니다.그것이 맞습니까?

제 경험상 Oracle은 간단한 술어를 사용하는 데 매우 능합니다.다음 테스트는 Oracle 11.2에서 수행되었습니다.10g의 모든 릴리스에서도 동일한 실행 계획을 생성할 수 있습니다.

(이전 버전을 실행하고 아래를 시도하셨다면 자유롭게 의견을 남겨주세요)

create table table1(a number, b number);
create table table2(a number, b number);

explain plan for
select *
  from (select a,b from table1
        union 
        select a,b from table2
       )
 where a > 1;

select * 
  from table(dbms_xplan.display(format=>'basic +predicate'));

PLAN_TABLE_OUTPUT
---------------------------------------
| Id  | Operation            | Name   |
---------------------------------------
|   0 | SELECT STATEMENT     |        |
|   1 |  VIEW                |        |
|   2 |   SORT UNIQUE        |        |
|   3 |    UNION-ALL         |        |
|*  4 |     TABLE ACCESS FULL| TABLE1 |
|*  5 |     TABLE ACCESS FULL| TABLE2 |
---------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------    
   4 - filter("A">1)
   5 - filter("A">1)

순서(4,5)에서 알 수 있듯이 술어는 아래로 푸시되어 정렬(연합) 전에 적용됩니다.

옵티마이저가 다음과 같은 서브쿼리 전체를 푸시다운하도록 할 수 없었습니다.

 where a = (select max(a) from empty_table)

또는 가입합니다.적절한 PK/FK의 제약이 있으면 가능한 일이지만, 분명히 제약이 있습니다.

메모: 몇 년 전 제 조언이 사실이었지만 Oracle의 옵티마이저는 개선되어 더 이상 중요하지 않게 되었습니다., 「」, 「」를 우선합니다.UNION ALL »UNION모든 데이터베이스에 없는 최적화에 의존하지 않도록 해야 합니다.

은 간한 the the the the the the the the the the 를 원합니다.WHEREbefore UNION '이렇게 하다'를 합니다.UNION ALL가면 ★★★★★★★★★★★★★★★★★★★.UNION ALL을 확인합니다.은 EXPLINE 출력을 할 수 .Oracle은 이 기능을 최적화 할 수 있을 정도로 스마트합니다.WHERE상태를 설정합니다.

을 사용하다UNION2개의 데이터 세트에 중복이 있는 경우는, 그것들을 삭제할 필요가 있다고 합니다. 때문에 암묵적인 것이 .GROUP BY3년 않았다고 Oracle을 통해 않는다는 것입니다.GROUP BY( ( ( ( ( ( ( 。따라서 Oracle은 필요 이상으로 큰 데이터 세트를 구성하고 그룹화한 다음 필터링해야 합니다.덧붙여서, (여기 것이 이기도 합니다.WHERE한 한 두는 것이 HAVING( ) 참참참참주 。

두 세트 않을 를 하십시오.UNION ALL은 마치 건치마 같은 것이다UNION데이터셋을 연결하지만 데이터 중복 제거를 시도하지 않습니다.이렇게 하면 고가의 그룹화 작업이 절약됩니다.제 경험상 이 수술을 이용할 수 있는 것은 매우 흔한 일입니다.

★★UNION ALL인 의미가 .GROUP BY이 경우 Oracle의 옵티마이저는 이를 통해 조건을 푸시하는 방법을 알고 있을 수 있습니다.Oracle을 테스트하기 위해 대기하고 있지 않기 때문에 직접 테스트해야 합니다.

주의사항입니다.

노력했다면

SELECT colA, colB FROM tableA WHERE colA > 1
UNION
SELECT colX, colA FROM tableB WHERE colA > 1

비교:

SELECT * 
  FROM (SELECT colA, colB FROM tableA
        UNION
        SELECT colX, colA FROM tableB) 
 WHERE colA > 1

두 번째 쿼리에서는 where 구의 colA가 실제로 테이블B의 colX를 가지므로 매우 다른 쿼리가 됩니다.이러한 방법으로 열의 별칭을 지정할 경우 혼란스러울 수 있습니다.

설명 계획을 검토해야 하지만 COL_A에 INDEX 또는 PARTION이 없는 한 두 테이블 모두에서 FULL TABLE SCAN이 표시됩니다.

이 점을 염두에 두고 첫 번째 예에서는 FULL TABLE SCAN과 마찬가지로 일부 데이터를 폐기합니다.그 결과는 UNION에 의해 분류되고 있으며, 중복된 데이터는 폐기됩니다.결과 세트가 표시됩니다.

두 번째 예에서는 두 테이블의 전체 내용을 끌어당깁니다.그 결과는 더 클 것 같다.그래서 UNION은 더 많은 데이터를 분류하고 복제품을 폐기하고 있습니다.그런 다음 원하는 결과 세트를 제공하기 위해 필터를 적용합니다.

일반적으로 데이터를 빨리 필터링할수록 데이터 세트가 작아지고 결과를 더 빨리 얻을 수 있습니다.여느 때와 마찬가지로 마일리지가 다를 수 있습니다.

SELECT * FROM (SELECT colA, colB FROM tableA UNION SELECT colA, colB FROM tableB) as tableC WHERE tableC.colA > 1

2개의 테이블에 동일한 필드 이름을 포함하는 결합을 사용하는 경우 하위 쿼리에 tableC(위 쿼리에서)로 이름을 지정해야 합니다. ★★★★★★★★★★★★★★★★★★★.WHERE조건은 다음과 같아야 한다.WHERE tableC.colA > 1

ColA에 대한 지표를 가지고 있는지 확인하고 둘 다 조사해서 시간을 재겠습니다.그게 가장 좋은 답이 될 거예요.

것요. - 뛰어요. - 뛰어요. - 뛰어요.EXPLAIN PLAN최적기가 무엇을 선택했는지 확인할 수 있습니다.그렇지 않으면 @rayman의 제안대로 둘 다 실행하고 시간을 재십시오.

SELECT colA, colB FROM tableA  WHERE colA > 1
UNION
SELECT colX, colA FROM tableB
SELECT * 
FROM (SELECT * FROM can
    UNION
    SELECT * FROM employee) as e
WHERE e.id = 1;

언급URL : https://stackoverflow.com/questions/5437507/union-with-where-clause

반응형