선택 * 대 선택 열


124

2/3 열만 필요 SELECT *하고 선택 쿼리에서 해당 열을 제공하는 대신 쿼리 하는 경우 더 많거나 적은 I / O 또는 메모리와 관련된 성능 저하가 있습니까?

필요없이 *를 선택하면 네트워크 오버 헤드가 나타날 수 있습니다.

그러나 선택 작업에서 데이터베이스 엔진은 항상 디스크에서 원자 튜플을 가져 오나요, 아니면 선택 작업에서 요청 된 열만 가져 오나요?

항상 튜플을 가져 오면 I / O 오버 헤드는 동일합니다.

동시에 튜플을 가져 오는 경우 튜플에서 요청 된 열을 제거하기위한 메모리 소비가있을 수 있습니다.

이 경우 select someColumn은 select *보다 메모리 오버 헤드가 더 많습니다.


질문하는 특정 RDBMS가 있습니까? 그것은 어떻게 가능 SELECT쿼리가 실행 / 처리 데이터베이스에서 데이터베이스에 다릅니다.
Lèse majesté

10
제쳐두고 PostgreSQL에서라고 말한 CREATE VIEW foo_view AS SELECT * FROM foo;다음 나중에 foo 테이블에 열을 추가하면 해당 열이 예상대로 foo_view에 자동으로 표시되지 않습니다. 즉, *이 컨텍스트에서는 SELECT가 아닌 한 번만 (보기 생성시) 확장됩니다. ALTER TABLE에서 발생하는 합병증으로 인해 (실제로는) *유해한 것으로 간주됩니다.
Joey Adams

@JoeyAdams-PostgresQL뿐만 아니라 Oracle의 동작이기도합니다.
APC

1
@OMG Ponies : 비슷한 게시물을 몰랐습니다. 그러나 이것들은 실제로 단순하지 않습니다. @ Lèse majesté : 저는 Generic RDBMS에 대해 이야기하고 있습니다. 특정 벤더 @Joey Adams에 대한 것이 아닙니다. 흠 나는 *가 안전하지 않다는 것을 알고 있습니다. 성능 문제에 대해 논의하고 싶습니다.
Neel Basu

답변:


31

항상 튜플을 가져 오므로 (테이블이 세로로 분할되어 열 조각으로 나뉘어 진 경우는 제외), 질문에 답하기 위해 성능 측면에서는 중요하지 않습니다. 그러나 다른 여러 가지 이유로 (아래) 항상 원하는 열을 이름별로 선택해야합니다.

(내가 익숙한 모든 공급 업체 RDBMS에서) 모든 것에 대한 기본 온 디스크 스토리지 구조 (테이블 데이터 포함)가 정의 된 I / O 페이지를 기반으로하기 때문에 항상 튜플을 가져옵니다 ( 예 : SQL Server에서 각 페이지는 8KB). 그리고 모든 I / O 읽기 또는 쓰기는 페이지별로 이루어집니다. 즉, 모든 쓰기 또는 읽기는 완전한 데이터 페이지입니다.

이러한 근본적인 구조적 제약으로 인해 결과적으로 데이터베이스의 각 데이터 행은 항상 하나의 페이지에만 있어야합니다. 여러 페이지의 데이터에 걸쳐있을 수 없습니다 (실제 blob 데이터가 별도의 페이지 청크에 저장되고 실제 테이블 행 열은 포인터 만 가져 오는 blob과 같은 특수한 경우 제외). 그러나 이러한 예외는 예외 일 뿐이며 일반적으로 특수한 경우를 제외하고는 적용되지 않습니다 (특수 유형의 데이터 또는 특수 상황에 대한 특정 최적화)
이러한 특수한 경우에도 일반적으로 데이터 자체의 실제 테이블 행 ( Blob에 대한 실제 데이터에 대한 포인터 등), 단일 IO 페이지에 저장되어야합니다.

예외. Select *OK 인 유일한 위치 는 다음과 같이 Existsor Not Existspredicate 절 뒤의 하위 쿼리 에 있습니다.

   Select colA, colB
   From table1 t1
   Where Exists (Select * From Table2
                 Where column = t1.colA)

편집 : @Mike Sherer의 의견을 다루기 위해 기술적으로는 특수 사례에 대한 약간의 정의와 미학적으로 모두 사실입니다. 첫째, 요청 된 열 집합이 일부 인덱스에 저장된 열의 하위 집합 인 경우에도 쿼리 프로세서는 동일한 이유로 요청 된 열뿐만 아니라 해당 색인에 저장된 모든 열을 가져와야합니다. 모든 I / O는 페이지 및 인덱스 데이터는 테이블 데이터와 마찬가지로 IO 페이지에 저장됩니다. 따라서 인덱스 페이지에 대해 "튜플"을 인덱스에 저장된 열 집합으로 정의하는 경우에도 문은 참입니다.
요점은 요청한 내용이 아니라 I / O 페이지에 저장된 내용을 기반으로 데이터를 가져오고 기본 테이블 I / O 페이지에 액세스하든 인덱스에 액세스하든 관계없이 데이터를 가져 오기 때문입니다. I / O 페이지.

사용하지 않아야하는 다른 이유 는 왜 유해한 것으로 간주됩니까?를Select * 참조하십시오 . :SELECT *


"항상 튜플을 가져옵니다"확실합니까? 흠 좋아 그래서 내가 옳았다. 이 경우 동일한 I / O 오버 select *헤드보다 메모리 오버 헤드가 적습니다 select column. 네트워크 오버 헤드를 남겨두면 select *오버 헤드가 적은 경우select column
Neel Basu

10
이것은 사실이 아닙니다. 내 머리 위에있는 한 가지 예는 MySQL에서 색인화 된 열의 값만 원하고 (예 : 행 존재 여부를 확인하기 위해) MyISAM 스토리지 엔진을 사용하는 경우입니다. MYI 파일은 메모리에있을 수 있으며 디스크로도 이동하지 않습니다!
Mike Sherov 2010-07-05

Ya 요청 된 튜플 세트가 메모리에 있으면 I / O가 없지만 특별한 경우입니다. 그래서 여름은 무엇입니까. 인덱싱 된 열을 선택하면 전체 튜플이 읽히지 않습니까? 그렇지 않으면 전체 튜플을 읽습니까?
Neel Basu

MySql이 어떻게 캐싱을 수행하는지 정확히 모르겠지만 SQL Server 및 Oracle에서는 데이터가 메모리 내 캐시에 있더라도 디스크에서 액세스 할 때와 동일한 페이지 구조를 사용하여 액세스합니다. 즉, 데이터 페이지 당 하나의 메모리 I / O가 필요합니다. 디스크에서와 똑같습니다. (물론 메모리 I / O가 디스크 I / O보다 훨씬 빠릅니다). 실제로, 이것이 캐싱 설계의 목표이며, 액세스 프로세스가 데이터 위치에 완전히 독립적이되도록 만드는 것입니다.
Charles Bretana

2
"다른 많은 이유로"에 대해 더 자세히 설명해 주시겠습니까? 나에게 명확하지 않았기 때문입니다. 성능이 중요하지 않은 경우 열 이름 요청에 관심이있는 이유는 무엇입니까?
Dennis

111

SELECT *프로덕션 코드에서 절대 사용해서는 안되는 몇 가지 이유가 있습니다 .

  • 원하는 것에 대한 힌트를 데이터베이스에 제공하지 않기 때문에 먼저 해당 테이블의 열을 결정하기 위해 테이블의 정의를 확인해야합니다. 이 조회에는 시간이 걸리지 만 단일 쿼리에서는 많지 않지만 시간이 지남에 따라 추가됩니다.

  • 열의 2/3 만 필요한 경우 디스크에서 검색하여 네트워크를 통해 전송해야하는 1/3의 데이터를 너무 많이 선택하는 것입니다.

  • 데이터의 특정 측면 (예 : 반환 된 열의 순서)에 의존하기 시작하면 테이블이 재구성되고 새 열이 추가 (또는 기존 열이 제거됨)되면 엄청나게 놀라 울 수 있습니다.

  • SQL Server에서 (다른 데이터베이스에 대해서는 확실하지 않음) 열 하위 집합이 필요한 경우 클러스터되지 않은 인덱스가 해당 요청을 처리 할 가능성이 항상 있습니다 (필요한 모든 열 포함). 를 사용하면 SELECT *처음부터 그 가능성을 포기하게됩니다. 이 특별한 경우에는 인덱스 페이지에서 데이터가 검색되므로 (필요한 모든 열이 포함 된 경우) 디스크 I / O 메모리 오버 헤드가 SELECT *....쿼리 를 수행하는 것보다 훨씬 적습니다 .

예, 처음에는 약간 더 많은 입력이 필요합니다 ( SQL Server 용 SQL 프롬프트 와 같은 도구 도 도움이 될 것입니다). 그러나 이것은 실제로 예외없이 규칙이있는 경우입니다. 프로덕션 코드에서 SELECT *를 사용하지 마십시오. 이제까지.


13
실제로 당신과 동의하는 동안, 당신은 테이블에서 열 데이터를 가져올 때 모든 경우에 확실히 정확합니다.이 질문이 다룹니다.) 그럼에도 불구 하고이 규칙이 모든 SQL 쿼리에 일반적이지 않다는 점을 지적하도록 저를 유도합니다. 특히, EXISTS 술어 뒤에 서브 쿼리에서 사용됩니다. (에서와 같이 Where Exists (Select * From ...) 사용 Select *은 확실히 문제가되지 않으며 일부 서클에서는 모범 사례로 간주됩니다.
Charles Bretana

3
@Charles Bretana : 예, IF EXISTS(SELECT *...특별한 경우입니다. 데이터가 실제로 검색되지 않았기 때문에 존재 여부를 확인하는 것뿐입니다. SELECT *는 문제가되지 않습니다 ...
marc_s 2010-07-05

1
내 테이블 중 하나에서 데이터를 검색 할 수있는 API를 개발하고 있다면 어떨까요? 사용자가 어떤 데이터에 관심이 있는지 알 수 없기 때문에 SELECT *가 허용 될 것이라고 생각합니까?
Simon Bengtsson 2014

1
@SimonBengtsson : 저는 여전히 이것에 대해 반대합니다. 고객에게 노출하고 싶지 않은 테이블의 특정 열에 "관리"데이터가 있다고 가정합니까? 나는 항상 가져올 열 목록을 명시 적으로 지정합니다
marc_s

1
사실입니다. API와 함께 사용하도록 특별히 설정된 뷰를 쿼리 할 때 어떻습니까?
Simon Bengtsson 2014

21

당신은해야한다 항상 에만 select열 실제로 필요. 더 많은 것 대신 더 적은 것을 선택하는 것이 결코 효율적이지 않으며, 클라이언트 측에서 인덱스별로 결과 열에 액세스 한 다음 테이블에 새 열을 추가하여 해당 인덱스가 올바르지 않게되는 것과 같은 예기치 않은 부작용도 적습니다.

액세스를 의미합니다. 멍청한 뇌가 여전히 깨어 있습니다.


3
클라이언트 측의 인덱스 및 추가 / 변경된 열과 같이 언뜻보기에 많이 생각하지 않을 것으로 생각되는 엣지 케이스의 경우 +1입니다.
Tomas Aschan 2010

1
예, 그러나 열에 숫자 인덱스를 사용하는 것이 일반적입니까? ORM을 사용하는 경우 항상 문자열 키 또는 속성 이름을 사용하여 열 데이터에 액세스했습니다.
Lèse majesté

11
오래 전에 이것을 본 주니어 프로그래머는 테이블에서 *를 선택하고 열 순서에 대해 가정했습니다. 다른 사람이 테이블을 변경하자마자 그의 모든 코드가 깨졌습니다. 우리가 얼마나 재미 있었는지.
Paul McKenzie

7
코드 가독성을 위해 일반적으로 열 순서를 사용하는 것은 나쁜 생각 일 것입니다 SELECT *.
Lèse majesté

2
와우, 클라이언트 코드에서 인덱스로 열에 액세스하는 것은 엄청나게 나쁜 생각 처럼 보입니다 . 그 문제 에 대해 어떤 식 으로든 결과 집합 열이 나타나는 순서에 의존하는 것은 나에게 매우 더럽습니다.
Matt Peterson

7

큰 Blob을 저장하지 않는 한 성능은 문제가되지 않습니다. SELECT *를 사용하지 않는 가장 큰 이유는 반환 된 행을 튜플로 사용하는 경우 스키마가 지정하는 순서에 관계없이 열이 다시 나타나고 변경되면 모든 코드를 수정해야하기 때문입니다.

반면에 사전 스타일 액세스를 사용하는 경우 항상 이름으로 액세스하기 때문에 열이 다시 들어오는 순서는 중요하지 않습니다.


6

이것은 즉시 유형의 열을 포함하는 내가 사용하고 있던 테이블을 생각하게합니다 blob. 일반적으로 몇 Mb초 크기의 JPEG 이미지가 포함 되어 있습니다.

말할 필요도없이 SELECT내가 정말로 필요로 하지 않는 한 나는 그 칼럼을하지 않았다 . 특히 여러 행을 선택했을 때 데이터를 떠 다니는 것은 번거 롭습니다.

그러나 일반적으로 테이블의 모든 열에 대해 쿼리한다는 것을 인정합니다.


20
LOB 열은 항상 SELECT *의 위험 중 가장 좋아하는 예입니다. 그래서 세 번째 단락을 읽을 때까지 당신을 찬성하려고했습니다. Tsk, tsk. 다른 개발자가 현재 이러한 열이없는 테이블에 BLOB를 추가하면 어떻게됩니까?
APC

1
@APC, 귀하의 의견을 더 많이 찬성 할 수 있기를 바랍니다. 엄청난 성능 저하를 일으키지 않고 컬럼을 추가하고 싶어하는 불쌍한 동료를 생각해보십시오! 몇 시간 후에 당신의 무고한 외모가 *를 선택하면 그들이 얼마나 화가 났는지 생각해보십시오.
Mike Sherov 2010

1
@ user256007, 예, BLOB 없이도 ... BLOB는 극단적 인 예를 보여줍니다. Charles에 대한 내 응답을 확인하십시오. 특정 열을 선택하면 디스크로 이동하지 않고도 메모리에서 데이터를 가져올 수있는 경우가 있습니다!
Mike Sherov 2010

1
@Richard, DB 성능 최적화가 주된 관심사가 아닐 때 유용하다고 생각합니다. 이는 99 %의 시간입니다. 대부분의 프레임 워크와 마찬가지로 순수한 성능을 희생하면서 더 빠른 개발을 가능하게하기 위해 사물을 일반화하는 경향이 있습니다. Knuth가 말했듯이 "조기 최적화는 모든 악의 근원입니다." select 열과 select *의 성능에 대해 걱정할 필요가있는 지점에 도달하면 (RoR에 대해 Twitter에 문의) 걱정하고 최적화 할 수 있습니다. 프레임 워크가이를 지원하기에 충분히 견고하지 않다면 잘못된 프레임 워크를 사용하고 있다고 말할 수 있습니다.
Mike Sherov 2010

1
@ user256007-일반적인 규칙은 "SELECT *를 사용하지 마십시오."입니다. marc_s의 답변은 이것이 왜 그런지에 대한 모든 정보를 담고 있습니다.
APC

6

SQL 선택 중에 DB는 SELECT * for SELECT a, b, c에 관계없이 항상 테이블의 메타 데이터를 참조합니다. 이유는 무엇입니까? 시스템에서 테이블의 구조 및 레이아웃에 대한 정보가 여기에 있기 때문입니다.

두 가지 이유로이 정보를 읽어야합니다. 하나는 단순히 문장을 컴파일하는 것입니다. 최소한 기존 테이블을 지정했는지 확인해야합니다. 또한 명령문이 마지막으로 실행 된 이후 데이터베이스 구조가 변경되었을 수 있습니다.

당연히 DB 메타 데이터는 시스템에 캐시되지만 여전히 수행해야하는 처리 중입니다.

다음으로 메타 데이터는 쿼리 계획을 생성하는 데 사용됩니다. 이것은 명령문이 컴파일 될 때마다 발생합니다. 다시 말하지만 이는 캐시 된 메타 데이터에 대해 실행되지만 항상 수행됩니다.

이 처리가 수행되지 않는 유일한 경우는 DB가 사전 컴파일 된 쿼리를 사용하거나 이전 쿼리를 캐시 한 경우입니다. 이것은 리터럴 SQL이 아닌 바인딩 매개 변수를 사용하기위한 인수입니다. "SELECT * FROM TABLE WHERE key = 1"은 "SELECT * FROM TABLE WHERE key =?"와 다른 쿼리입니다. "1"은 호출에 바인딩됩니다.

DB는 작업을 위해 페이지 캐싱에 크게 의존합니다. 많은 최신 DB는 메모리에 완전히 맞출 수있을만큼 작습니다 (또는 최신 메모리는 많은 DB에 맞을만큼 충분히 큽니다). 그런 다음 백엔드의 기본 I / O 비용은 로깅 및 페이지 플러시입니다.

그러나 여전히 DB 용 디스크를 사용하는 경우 많은 시스템에서 수행하는 기본 최적화는 테이블 자체가 아닌 인덱스의 데이터에 의존하는 것입니다.

당신이 가지고 있다면:

CREATE TABLE customer (
    id INTEGER NOT NULL PRIMARY KEY,
    name VARCHAR(150) NOT NULL,
    city VARCHAR(30),
    state VARCHAR(30),
    zip VARCHAR(10));

CREATE INDEX k1_customer ON customer(id, name);

그런 다음 "SELECT id, name FROM customer WHERE id = 1"을 수행하면 DB가 테이블이 아닌 인덱스에서이 데이터를 가져올 가능성이 큽니다.

왜? 어쨌든 쿼리를 충족시키기 위해 인덱스를 사용할 가능성이 높으며 (테이블 스캔과 비교) where 절에서 'name'이 사용되지 않더라도 해당 인덱스는 여전히 쿼리에 가장 적합한 옵션입니다.

이제 데이터베이스에는 쿼리를 충족하는 데 필요한 모든 데이터가 있으므로 테이블 페이지 자체를 조회 할 이유가 없습니다. 인덱스를 사용하면 일반적으로 테이블에 비해 인덱스의 행 밀도가 높기 때문에 디스크 트래픽이 줄어 듭니다.

이것은 일부 데이터베이스에서 사용되는 특정 최적화 기술에 대한 손으로 물결 치는 설명입니다. 많은 사람들이 몇 가지 최적화 및 조정 기술을 가지고 있습니다.

결국 SELECT *는 수동으로 입력해야하는 동적 쿼리에 유용하며 "실제 코드"에는 사용하지 않습니다. 개별 열의 식별은 DB가 쿼리를 최적화하는 데 사용할 수있는 더 많은 정보를 제공하고 스키마 변경 등에 대해 코드에서 더 나은 제어를 제공합니다.


윌, 나는 당신이 PRIMARY KEY와 함께 NOT NULL을 사용하기 때문에 당신의 대답을 거절했습니다. 이런 식으로 작성해야하는 타당한 이유가 있습니까?
학습자

4

나는 당신의 앱을 유지하는 성능과 시설을 숙고했기 때문에 귀하의 질문에 대한 정확한 대답은 없다고 생각합니다. Select column더 성능이 select *좋지만 지향 객체 시스템을 개발하는 경우 사용을 좋아 object.properties하고 앱의 모든 부분에서 속성이 필요할 수 있습니다. 그렇지 않으면 특별한 상황에서 속성을 가져 오기 위해 더 많은 메서드를 작성해야합니다. select *모든 속성을 사용 하고 채 웁니다. 앱은 사용하여 좋은 성능을 가져야하며 select *경우에 따라 성능 향상을 위해 선택 열을 사용해야합니다. 그러면 성능이 필요할 때 앱을 작성하고 유지 관리하는 기능과 성능이라는 두 가지 세상에서 더 나은 결과를 얻을 수 있습니다.


4

여기에서 받아 들여지는 대답은 잘못되었습니다. 나는 다른 질문 이 이것의 중복으로 닫 혔을 때 이것을 발견했습니다 (내가 여전히 대답을 쓰는 동안-grr-따라서 아래 SQL은 다른 질문을 참조합니다).

항상 SELECT 속성, 속성을 사용해야합니다 .... NOT SELECT *

주로 성능 문제입니다.

사용자로부터 이름 선택 WHERE name = 'John';

매우 유용한 예가 아닙니다. 대신 고려하십시오.

SELECT telephone FROM users WHERE name='John';

(이름, 전화)에 대한 색인이있는 경우 테이블에서 관련 값을 조회하지 않고도 쿼리를 해결할 수 있습니다 . 포함 색인이 있습니다.

또한 테이블에 사용자 사진, 업로드 된 CV 및 스프레드 시트가 포함 된 BLOB가 있다고 가정합니다. SELECT *를 사용하면이 모든 정보를 DBMS 버퍼로 다시 가져옵니다 (캐시에서 다른 유용한 정보를 강제로 가져옴). 그런 다음 네트워크의 가동 시간과 중복되는 데이터에 대한 클라이언트의 메모리를 사용하여 클라이언트로 모두 전송됩니다.

클라이언트가 데이터를 열거 형 배열 (예 : PHP의 mysql_fetch_array ($ x, MYSQL_NUM))로 검색하는 경우에도 기능 문제가 발생할 수 있습니다. 아마도 코드가 작성되었을 때 'telephone'이 SELECT *에 의해 반환되는 세 번째 열 이었지만 누군가가 와서 'telephone'앞에있는 테이블에 이메일 주소를 추가하기로 결정했습니다. 이제 원하는 필드가 4 번째 열로 이동됩니다.


2

어떤 방식 으로든 일을하는 데에는 이유가 있습니다. PostgreSQL에서 SELECT *를 많이 사용합니다. 특히 저장 프로 시저에서는 명시 적 열 목록으로는 할 수없는 PostgreSQL의 SELECT *로 할 수있는 일이 많기 때문입니다. Informix에서 마찬가지로 상속 된 테이블 트리에 대한 SELECT *는 하위 테이블의 추가 열도 반환되기 때문에 명시 적 열 목록은 그렇지 않은 반면, 상속 된 테이블 트리에 대한 SELECT *는 들쭉날쭉 한 행을 제공 할 수 있습니다.

PostgreSQL에서이 작업을 수행하는 주된 이유는 테이블에 맞는 올바른 형식의 유형을 얻도록하기 때문입니다. 이를 통해 결과를 PostgreSQL에서 테이블 유형으로 사용할 수 있습니다. 이것은 또한 고정 열 목록보다 쿼리에서 더 많은 옵션을 허용합니다.

반면에 고정 된 열 목록은 db 스키마가 특정 방식으로 변경되지 않았는지 확인하는 애플리케이션 수준의 검사를 제공하며 이는 도움이 될 수 있습니다. (나는 다른 수준에서 그러한 검사를합니다.)

성능에 관해서는 유형을 반환하는 VIEW 및 저장 프로 시저를 사용하는 경향이 있습니다 (그런 다음 저장 프로 시저 내부의 열 목록). 이를 통해 반환되는 유형을 제어 할 수 있습니다.

그러나 일반적으로 기본 테이블이 아닌 추상화 계층에 대해 SELECT *를 사용하고 있음을 명심하십시오.


2

이 기사에서 가져온 참조 :

SELECT * 없음 : 그 당시”SELECT *”를 사용하는 경우 데이터베이스에서 더 많은 열을 선택하고이 열 중 일부는 응용 프로그램에서 사용되지 않을 수 있습니다. 이로 인해 데이터베이스 시스템에 추가 비용과로드가 발생하고 더 많은 데이터가 네트워크를 통해 이동합니다.

* SELECT * : 특별한 요구 사항이 있고 동적 환경을 생성 한 경우 열을 추가하거나 삭제할 때 자동으로 애플리케이션 코드에 의해 처리됩니다. 이 특별한 경우에는 애플리케이션 및 데이터베이스 코드를 변경할 필요가 없으며 이는 프로덕션 환경에 자동으로 영향을 미칩니다. 이 경우 "SELECT *"를 사용할 수 있습니다.


0

여기에서 볼 수없는 토론에 뉘앙스를 추가하기 위해 : I / O 측면에서 열 지향 스토리지가 있는 데이터베이스를 사용하는 경우 특정 쿼리 만 쿼리하면 I / O를 훨씬 줄일 수 있습니다. 열. SSD로 이동함에 따라 이점은 행 지향 스토리지에 비해 약간 작을 수 있지만 a) 관심있는 열이 포함 된 블록 만 읽는 것 b) 압축은 일반적으로 디스크의 데이터 크기를 크게 줄여 주므로 디스크에서 읽은 데이터 양.

열 지향 스토리지에 익숙하지 않은 경우 Postgres 구현 중 하나는 Citus Data에서, 다른 하나는 Greenplum, 또 다른 Paraccel이며, 다른 하나는 Amazon Redshift입니다. MySQL에는 거의 없어진 InfiniDB 인 Infobright가 있습니다. 기타 상용 제품으로는 HP의 Vertica, Sybase IQ, Teradata ...


-1
select * from table1 INTERSECT  select * from table2

같은

select distinct t1 from table1 where Exists (select t2 from table2 where table1.t1 = t2 )

당신은 그것을 강조하고 Ctrl 키를 + K를 타격하여 코드 형식을 주시겠습니까
WhatsThePoint
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.