복붙노트

[SQL] 전혀 다른 테이블에있는 행에 대응 한 하나 개의 테이블에 행을 찾는 방법

SQL

전혀 다른 테이블에있는 행에 대응 한 하나 개의 테이블에 행을 찾는 방법

두 테이블 사이 1 관계 : 나는 일이있다. 나는 B. 나는이 쿼리를 사용하여 테이블의 해당 행이없는 테이블 A의 모든 행을 찾으려면 :

SELECT id 
  FROM tableA 
 WHERE id NOT IN (SELECT id 
                    FROM tableB) 
ORDER BY id desc

ID가 두 테이블의 기본 키입니다. 외에도 기본 키 인덱스에서, 나는 또한 TABLEA (ID 내림차순)에 인덱스가 있습니다.

H2 (자바 임베디드 데이터베이스), TableB의 전체 테이블 스캔이 결과를 사용하여. 나는 전체 테이블 스캔을 방지합니다.

어떻게 신속하게 실행하려면이 쿼리를 다시 작성할 수 있습니까? 무엇 인덱스해야 내가해야?

해결법

  1. ==============================

    1.

    select tableA.id from tableA left outer join tableB on (tableA.id = tableB.id)
    where tableB.id is null
    order by tableA.id desc 
    

    당신의 DB 인덱스 교차점을 수행하는 방법을 알고 있다면, 이것은 단지 기본 키 인덱스를 터치합니다

  2. ==============================

    2.때로는 빠르게 왼쪽 결합보다이기 때문에 당신은 또한 사용은 존재 할 수 있습니다. 당신은 그들이 당신이 사용하고자하는 하나 파악하는 벤치 마크해야 할 것이다.

    때로는 빠르게 왼쪽 결합보다이기 때문에 당신은 또한 사용은 존재 할 수 있습니다. 당신은 그들이 당신이 사용하고자하는 하나 파악하는 벤치 마크해야 할 것이다.

    select
        id
    from
        tableA a
    where
        not exists
        (select 1 from tableB b where b.id = a.id)
    

    그 왼쪽 조인을보다 효율적으로 할 수있는 표시하려면, 여기에 SQL Server 2008의 이러한 쿼리의 실행 계획을이다 :

    왼쪽 가입 - 전체 하위 트리 비용 : 1.09724를 :

    존재 - 전체 하위 트리 비용 : 1.07421 :

  3. ==============================

    3.당신은 TableB의 모든 ID에 대해 TABLEA의 모든 ID를 확인해야합니다. (Oracle과 같은) 완전한 기능의 RDBMS는 FAST 인덱스 스캔 전체에 그 최적화 할 수있을 모두에서 테이블을 만지지 것입니다. 나는 H2의 최적화와 스마트로인지 모른다.

    당신은 TableB의 모든 ID에 대해 TABLEA의 모든 ID를 확인해야합니다. (Oracle과 같은) 완전한 기능의 RDBMS는 FAST 인덱스 스캔 전체에 그 최적화 할 수있을 모두에서 테이블을 만지지 것입니다. 나는 H2의 최적화와 스마트로인지 모른다.

    H2는 당신이 시도해야하므로 MINUS 구문을 지원하지 않습니다

    select id from tableA
    minus
    select id from tableB
    order by id desc
    

    즉 빠르게 수행 할 수있다; 그것은 확실히 가치가 벤치마킹입니다.

  4. ==============================

    4.내 작은 데이터 세트의 경우, 오라클은 거의 모든 쿼리 테이블을 건드리지 않고 기본 키 인덱스를 사용하는 동일한 계획을 제공합니다. 예외는 적은 수의 일치 높은 계획 비용에도 불구하고 취득 할 관리하는 MINUS 버전입니다.

    내 작은 데이터 세트의 경우, 오라클은 거의 모든 쿼리 테이블을 건드리지 않고 기본 키 인덱스를 사용하는 동일한 계획을 제공합니다. 예외는 적은 수의 일치 높은 계획 비용에도 불구하고 취득 할 관리하는 MINUS 버전입니다.

    --Create Sample Data.
    d r o p table tableA;
    d r o p table tableB;
    
    create table tableA as (
       select rownum-1 ID, chr(rownum-1+70) bb, chr(rownum-1+100) cc 
          from dual connect by rownum<=4
    );
    
    create table tableB as (
       select rownum ID, chr(rownum+70) data1, chr(rownum+100) cc from dual
       UNION ALL
       select rownum+2 ID, chr(rownum+70) data1, chr(rownum+100) cc 
          from dual connect by rownum<=3
    );
    
    a l t e r table tableA Add Primary Key (ID);
    a l t e r table tableB Add Primary Key (ID);
    
    --View Tables.
    select * from tableA;
    select * from tableB;
    
    --Find all rows in tableA that don't have a corresponding row in tableB.
    
    --Method 1.
    SELECT id FROM tableA WHERE id NOT IN (SELECT id FROM tableB) ORDER BY id DESC;
    
    --Method 2.
    SELECT tableA.id FROM tableA LEFT JOIN tableB ON (tableA.id = tableB.id)
    WHERE tableB.id IS NULL ORDER BY tableA.id DESC;
    
    --Method 3.
    SELECT id FROM tableA a WHERE NOT EXISTS (SELECT 1 FROM tableB b WHERE b.id = a.id) 
       ORDER BY id DESC;
    
    --Method 4.
    SELECT id FROM tableA
    MINUS
    SELECT id FROM tableB ORDER BY id DESC;
    
  5. ==============================

    5.나는 당신이하는 이러한 방법은 H2 (또는 모두가 작동하는 경우)에 가장 좋은 뜻을 말할 수 없다,하지만 난 TSQL에서 사용할 수있는 (좋은) 모든 방법을 자세히 기사를 쓰고 않았다. 당신은 그들에게 기회를주고 그 중 하나가 당신을 위해 작동하는지 볼 수 있습니다 :

    나는 당신이하는 이러한 방법은 H2 (또는 모두가 작동하는 경우)에 가장 좋은 뜻을 말할 수 없다,하지만 난 TSQL에서 사용할 수있는 (좋은) 모든 방법을 자세히 기사를 쓰고 않았다. 당신은 그들에게 기회를주고 그 중 하나가 당신을 위해 작동하는지 볼 수 있습니다 :

    http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=QueryBasedUponAbsenceOfData&referringTitle=Home

  6. ==============================

    6.

    select parentTable.id from parentTable
    left outer join childTable on (parentTable.id = childTable.parentTableID) 
    where childTable.id is null
    
  7. from https://stackoverflow.com/questions/1415438/how-to-find-rows-in-one-table-that-have-no-corresponding-row-in-another-table by cc-by-sa and MIT license