복붙노트

[SQL] 선택 열에 대 선택 *

SQL

선택 열에 대 선택 *

난 그냥 2/3 열을 필요로하고 내가 대신 선택 쿼리에서 그 열을 제공하는의 * 선택 쿼리 경우, 더 / 덜 I / O 나 메모리 관련 성능 저하가?

내가 필요없이 선택 *을 할 경우 네트워크 오버 헤드가있을 수 있습니다.

그러나 선택 작업으로, 데이터베이스 엔진은 항상 디스크에서 원자 튜플을 끌어 않거나 만 선택 조작에서 요구하는 열을 끌어합니까?

항상 나는 튜플을 끌어 경우 / O 오버 헤드 동일합니다.

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

그런 경우가 있다면 그래서, 선택의보다 더 많은 메모리 오버 헤드를 가지고 몇 가지 열을 선택 *

해결법

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

    1.그것은 성능 측면에서 중요하지 않습니다, 당신이 묻는 질문에 대답하기 위해, 그래서 - 항상 (열 조각으로 깨진 테이블을 수직으로 분할 된 경우를 제외하고) 튜플을 가져옵니다. 그러나 많은 다른 이유로, (아래) 당신은 항상 이름으로, 특히 당신이 원하는 그 열을 선택해야합니다.

    그것은 성능 측면에서 중요하지 않습니다, 당신이 묻는 질문에 대답하기 위해, 그래서 - 항상 (열 조각으로 깨진 테이블을 수직으로 분할 된 경우를 제외하고) 튜플을 가져옵니다. 그러나 많은 다른 이유로, (아래) 당신은 항상 이름으로, 특히 당신이 원하는 그 열을 선택해야합니다.

    (테이블 데이터 포함) 모두를위한 기본에 디스크 스토리지 구조를 (모든 업체에서 내가 익숙 RDBMS) 때문에 항상 튜플를 가져옵니다 예에 대한 SQL 서버에 정의 된 I / O 페이지 (을 기반으로, 각각의 페이지입니다 8킬로바이트). 그리고 모든 I / O를 읽거나 쓰기 페이지 .. 즉 것입니다, 모든 쓰기 또는 읽기 데이터의 전체 페이지입니다.

    이 때문에 기본 구조 제약, 결과는 데이터베이스에있는 데이터의 각 행은 항상 하나 하나 개의 페이지에 있어야한다는 것입니다. (... 실제 BLOB 데이터는 별도의 페이지-덩어리에 저장되어있는 모양, 같은 특별한 일을 제외하고, 실제 테이블 행 열은 만 포인터를 가져옵니다)는 데이터의 여러 페이지에 걸쳐 수 없습니다. 그러나 이러한 예외는 그 예외가 있으며, 일반적으로 (데이터의 특별한 유형 또는 특별한 상황에 대한 특정 최적화에 대한) 특별한 경우를 제외하고는 적용되지 않습니다 심지어 이러한 특별한 경우에, 일반적으로 (블롭, 또는 무엇이든에 대한 실제 데이터에 대한 포인터를 포함) 데이터 자체의 실제 테이블 행, 그것은 하나의 IO 페이지에 저장해야합니다 ...

    예외. 이 존재하거나하지 같이 술어 절을 존재 후 선택 * 확인되는 유일한 장소는 하위 쿼리에 있습니다 :

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

    편집 : 주소 @ 마이크 쉐러 주석에, 네, 그것은, 기술적으로, 당신의 특별한 경우에 대한 정의의 비트와 함께, 미학적 사실이다. 모든 I / O가에서 수행되어야합니다 - 먼저, 요청 된 열 세트가 어떤 인덱스에 저장된의 하위 집합 경우에도 쿼리 프로세서가 인덱스에 저장된 모든 열을 인출해야합니다뿐만 아니라 사람이 같은 이유로, 요청 페이지 및 인덱스 데이터는 단지 테이블 데이터와 같은 IO 페이지에 저장됩니다. 인덱스에 저장된 열 집합으로 인덱스 페이지에 대해 "튜플"를 정의한다면, 문은 여전히 ​​사실이다. 포인트가는 I / O 페이지에 저장되어있는 내용에 따라 데이터를 가져 오는 것입니다 때문에 문이 아니라 당신이 / O 페이지 또는 인덱스를 요청하고 기본 테이블 I에 액세스하는 여부를이 사실 무엇을 미학적 사실이다 I / O 페이지.

    다른 이유는 선택 *를 사용하지를 들어 SELECT *는 유해한 것으로 간주됩니다 왜 보이지? :

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

    2.당신이 생산 코드에 SELECT *를 사용하지 않습니다 (결코 적)해야 몇 가지 이유가 있습니다 :

    당신이 생산 코드에 SELECT *를 사용하지 않습니다 (결코 적)해야 몇 가지 이유가 있습니다 :

    네, 처음에 입력 조금 더 소요 (도구가 SQL Server에 대한 프롬프트 SQL처럼 심지어 당신을 도울 것입니다 거기에) - 그러나 이것은 예외없는 규칙이있다 한 경우 정말 : 이제까지 당신의 생산 코드에 SELECT *를 사용하지 않는가. 이제까지.

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

    3.당신은 항상 만이 실제로 필요로하는 열을 선택해야합니다. 적은 대신에 이상 선택 덜 효율적 결코, 당신은 또한 적은 예상치 못한 부작용으로 실행 - 후 가진, 인덱스를 클라이언트 측에 결과 열에 액세스처럼 그 인덱스는 테이블에 새 열을 추가하여 잘못된된다.

    당신은 항상 만이 실제로 필요로하는 열을 선택해야합니다. 적은 대신에 이상 선택 덜 효율적 결코, 당신은 또한 적은 예상치 못한 부작용으로 실행 - 후 가진, 인덱스를 클라이언트 측에 결과 열에 액세스처럼 그 인덱스는 테이블에 새 열을 추가하여 잘못된된다.

    [편집] : 박하 액세스. 바보의 뇌는 여전히 깨어.

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

    4.당신이 큰 모양을 저장하지 않는 한, 성능은 문제가되지 않습니다. 가장 큰 이유는 SELECT를 사용하지 * 당신이 튜플로 반환 된 행을 사용하는 경우, 열이 다시 스키마가 지정하는 일이 순서대로 와서, 그리고 그 변경하는 경우 모든 코드를 수정해야 할 것입니다.

    당신이 큰 모양을 저장하지 않는 한, 성능은 문제가되지 않습니다. 가장 큰 이유는 SELECT를 사용하지 * 당신이 튜플로 반환 된 행을 사용하는 경우, 열이 다시 스키마가 지정하는 일이 순서대로 와서, 그리고 그 변경하는 경우 모든 코드를 수정해야 할 것입니다.

    당신이 사전 스타일의 액세스를 사용하는 경우 다른 한편으로, 열 다시 당신은 항상 이름을 액세스하기 때문에 와서 주문 중요하지 않습니다.

  5. ==============================

    5.이것은 바로 내가 형 방울의 열을 포함 내가 사용 된 테이블의 생각하게한다; 보통 JPEG 이미지 크기가 몇 MBS가 포함되어 있습니다.

    이것은 바로 내가 형 방울의 열을 포함 내가 사용 된 테이블의 생각하게한다; 보통 JPEG 이미지 크기가 몇 MBS가 포함되어 있습니다.

    난 정말 그것을 필요로하지 않는 한 나는 그 열을 선택하지 않은 말할 필요도없이. 주위에 떠있는 데이터를 갖는 - 나는 대해 여러 개의 행을 선택, 특히 - 다만 번거 로움이었다.

    그러나, 나는 그렇지 않으면 보통 테이블의 모든 열을 쿼리 것을 인정합니다.

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

    6.는 SQL 선택시, DB에 관계없이 항상이 SELECT에 대한 SELECT *는 A, B, C의 여부의 테이블에 대한 메타 데이터를 참조 할 것입니다 ... 왜? 그건 Becuase 시스템 테이블의 구조에 대한 정보와 레이아웃입니다.

    는 SQL 선택시, DB에 관계없이 항상이 SELECT에 대한 SELECT *는 A, B, C의 여부의 테이블에 대한 메타 데이터를 참조 할 것입니다 ... 왜? 그건 Becuase 시스템 테이블의 구조에 대한 정보와 레이아웃입니다.

    그것은 두 가지 이유로이 정보를 읽을 수 있습니다. 하나는 단순히 문을 컴파일합니다. 그것은 당신이 최소한 기존 테이블을 지정할 수 있도록 할 필요가있다. 또한, 데이터베이스 구조는 문이 실행 된 마지막 시간 이후 변경되었을 수 있습니다.

    이제, 분명히, DB 메타 데이터는 시스템에 캐시,하지만 여전히 필요가 수행 할 수 있음을 처리합니다.

    다음, 메타 데이터는 쿼리 계획을 생성하는 데 사용됩니다. 이 명령문이 아니라 컴파일 할 때마다 발생합니다. 다시 말하지만, 캐시 메타 데이터에 대해이 실행은 있지만 항상 이루어집니다.

    이 처리가 수행되지 않습니다 유일한 시간은 DB가 미리 컴파일 된 쿼리를 사용하거나, 이전 쿼리를 캐시 때입니다. 이 바인딩 매개 변수보다는 리터럴 SQL을 사용하기위한 인수입니다. "SELECT * FROM TABLE WHERE 키 = 1"과는 다른 쿼리입니다 "WHERE 키 = 테이블에서 SELECT *가?" 과 "1"호출에 바인딩됩니다.

    데시벨이 일을 위해 캐시 페이지에 크게 의존하고있다. 많은 현대 데시벨은 (현대 메모리가 많은 데시벨에 맞게 충분히 큰이며, 아마도 내가 말을해야, 또는) 정도로 작은 메모리에 완전히 맞게한다. 그런 다음 백 엔드에 기본 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);
    

    그런 다음, 당신 DB 오히려 테이블에서보다 인덱스에서이 데이터를 가져옵니다 가능성이 높다은 "ID = 1 WHERE 고객의 ID, 이름을 선택"경우.

    왜? 이 지수는 여전히 쿼리에 대한 최선의 선택이 될 것입니다, 그것은 가능성 (테이블 스캔 대) 쿼리를 만족시키기 위해 어쨌든 인덱스를 사용하며, 비록 '이름'where 절에 사용되지 않습니다.

    이제 데이터베이스가 쿼리를 만족하는 데 필요한 모든 데이터를 가지고, 그래서 테이블 페이지 자신을 공격 할 이유가 없습니다. 적은 디스크 트래픽 인덱스 결과를 사용하면 일반적으로 표 대 인덱스의 행보다 높은 밀도를 가지고 있기 때문이다.

    이것은 일부 데이터베이스에서 사용하는 특정 최적화 기법의 손 물결 모양의 설명이다. 많은 사람들이 여러 가지 최적화 및 튜닝 기술을 가지고있다.

    결국, SELECT * 당신 손으로 입력 할 필요가 동적 쿼리에 유용합니다, 나는 "실제 코드"를 위해 그것을 사용하지 않을 것입니다. 개별 열 식별이 DB를이 쿼리를 최적화하는 데 사용할 수있는 자세한 정보를 제공하고, 스키마 변경 등에 대해 코드에서 더 나은 제어 할 수 있습니다

  7. ==============================

    7.난 당신이 응용 프로그램을 유지 관리의 성능과 기능을 숙고 때문에 귀하의 질문에 대한 정확한 답이 없다 생각합니다. 선택 열은 선택 * 더 performatic,하지만 당신은 객체 지향 시스템을 개발하는 경우, 당신은 사용 object.properties을 좋아하고 당신이 다음의 속성을 얻기 위해 더 많은 방법을 쓸 필요가 앱의 어떤 부분의 속성을 필요로 할 수 있습니다 특별한 상황이 당신이 선택 *를 사용하여 모든 속성을 채우지 않는 경우. 귀하의 애플 리케이션을 선택 *를 사용하여 좋은 성능을 필요하고 어떤 경우에 당신은 성능 향상을 위해 선택 열을 사용해야합니다. 그럼 당신은 쓰기에 더 나은 두 세계, 시설이 있고 성능을 필요로 할 때 애플 리케이션과 성능을 유지합니다.

    난 당신이 응용 프로그램을 유지 관리의 성능과 기능을 숙고 때문에 귀하의 질문에 대한 정확한 답이 없다 생각합니다. 선택 열은 선택 * 더 performatic,하지만 당신은 객체 지향 시스템을 개발하는 경우, 당신은 사용 object.properties을 좋아하고 당신이 다음의 속성을 얻기 위해 더 많은 방법을 쓸 필요가 앱의 어떤 부분의 속성을 필요로 할 수 있습니다 특별한 상황이 당신이 선택 *를 사용하여 모든 속성을 채우지 않는 경우. 귀하의 애플 리케이션을 선택 *를 사용하여 좋은 성능을 필요하고 어떤 경우에 당신은 성능 향상을 위해 선택 열을 사용해야합니다. 그럼 당신은 쓰기에 더 나은 두 세계, 시설이 있고 성능을 필요로 할 때 애플 리케이션과 성능을 유지합니다.

  8. ==============================

    8.여기 허용 대답은 잘못된 것입니다. 또 다른 질문이의 중복으로 폐쇄되었을 때 (- GRR - 참조 아래 따라서 SQL 다른 질문을 난 아직도 내 대답을 쓰는 동안) 나는이 가로 질러왔다.

    여기 허용 대답은 잘못된 것입니다. 또 다른 질문이의 중복으로 폐쇄되었을 때 (- GRR - 참조 아래 따라서 SQL 다른 질문을 난 아직도 내 대답을 쓰는 동안) 나는이 가로 질러왔다.

    당신은 항상 선택 속성, 속성을 사용해야합니다 .... 선택하지 *

    이 성능 문제를 주로합니다.

    매우 유용한 예가 아니다. 대신 고려 :

    SELECT telephone FROM users WHERE name='John';
    

    다음 쿼리는 테이블에서 관련 값을 조회 할 필요없이 해결 될 수 있습니다 (이름, 전화)에 대한 인덱스가있는 경우 - 커버링 인덱스가있다.

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

    또한 기능적인 문제의 원인 클라이언트 (예 : PHP의로 MYSQL_ASSOC ($ X, MYSQL_NUM) 등) 열거 된 배열로 데이터를 검색 할 수 있습니다. 아마 코드가 '전화'기록 된 경우 SELECT *에 의해 반환되는 세 번째 열은이었다, 그러나 누군가가 따라 오는 '전화'앞에 배치 된 테이블에 이메일 주소를 추가하기로 결정합니다. 원하는 필드는 이제 4 번째 칼럼으로 이동한다.

  9. ==============================

    9.가지 중 하나의 방법을 수행하기위한 이유가있다. 난 당신이 특히 저장 프로 시저, 명시 적 열 목록과 함께 할 수 없어 PostgreSQL의에서 * 당신이 SELECT와 함께 할 수있는 일들이 많이 있기 때문에 * PostgreSQL을에 많이 사용을 선택합니다. 마찬가지로 인포믹스에서, 명시 적 컬럼 목록이 자식 테이블의 추가 열이 아니라 반환 할 수 없기 때문에 동안 행을 들쭉날쭉 줄 수있는 상속 테이블 트리를 통해 SELECT *.

    가지 중 하나의 방법을 수행하기위한 이유가있다. 난 당신이 특히 저장 프로 시저, 명시 적 열 목록과 함께 할 수 없어 PostgreSQL의에서 * 당신이 SELECT와 함께 할 수있는 일들이 많이 있기 때문에 * PostgreSQL을에 많이 사용을 선택합니다. 마찬가지로 인포믹스에서, 명시 적 컬럼 목록이 자식 테이블의 추가 열이 아니라 반환 할 수 없기 때문에 동안 행을 들쭉날쭉 줄 수있는 상속 테이블 트리를 통해 SELECT *.

    내가 PostgreSQL의에서이 작업을 수행 주된 이유는 내가 테이블에 잘 형성 유형의 특정 보장받을 수 있다는 것입니다. 이 날 결과를 가져과 PostgreSQL의 테이블 형태로 사용할 수 있습니다. 이것은 또한 것 견고한 열 목록보다 쿼리에 더 많은 옵션을 할 수 있습니다.

    반면에, 단단한 열 목록은 DB 스키마는 특정 방식으로 변경되지 않은이 도움이 될 수있는 당신에게 응용 프로그램 수준의 검사를 제공합니다. (나는 다른 수준에서 이러한 검사를 않습니다.)

    성능에 관해서는, I는 (다음 컬럼리스트 저장 프로 시저 내부) 타입을 리턴 뷰 및 저장 프로 시저를 사용하는 경향이있다. 이 유형은 반환되는 것을 나를 제어 할 수 있습니다.

    그러나 추상화 계층에 대해 오히려 기본 테이블보다 보통 * 내가 SELECT를 사용하고 명심하십시오.

  10. ==============================

    10.이 문서에서 가져온 참조 :

    이 문서에서 가져온 참조 :

    SELECT없이 * : 때 당신이 "SELECT *"사용하는 데이터베이스에서 더 많은 열을 선택하고이 칼럼의 일부 응용 프로그램에서 사용되지 않을 수 있습니다 그 시간에. 이 데이터베이스 시스템과 네트워크를 통해 더 많은 데이터 여행에 대한 추가 비용 및 부하를 생성합니다.

    SELECT와 * : 당신은 특별한 요구 사항 및 생성 된 동적 환경이있는 경우 추가 또는 삭제 열은 자동으로 응용 프로그램 코드에 의해 처리 할 때. 이 특별한 경우에는 변경 응용 프로그램 및 데이터베이스 코드를 필요로하지 않는이 자동으로 프로덕션 환경에 영향을 미칠 것입니다. 이 경우 "SELECT *"를 사용할 수 있습니다.

  11. ==============================

    11.그냥 내가 여기에 표시되지 않습니다 토론에 뉘앙스를 추가합니다 : I / O의 측면에서, 당신은 열 지향적 인 스토리지와 데이터베이스를 사용하는 경우는 훨씬 적은 I / O를 할 수있는 경우에만 쿼리 특정위한 열. 우리의 SSD로 이동하면 혜택이 조금 작은 대 행 지향 저장 될 수 있지만, 거기 수있는) 만 일반적으로 크게 때문에 디스크에있는 데이터의 크기를 줄여 B) 압축, 신경 열을 포함하는 블록을 읽고 데이터의 볼륨이 디스크에서 읽어 보시기 바랍니다.

    그냥 내가 여기에 표시되지 않습니다 토론에 뉘앙스를 추가합니다 : I / O의 측면에서, 당신은 열 지향적 인 스토리지와 데이터베이스를 사용하는 경우는 훨씬 적은 I / O를 할 수있는 경우에만 쿼리 특정위한 열. 우리의 SSD로 이동하면 혜택이 조금 작은 대 행 지향 저장 될 수 있지만, 거기 수있는) 만 일반적으로 크게 때문에 디스크에있는 데이터의 크기를 줄여 B) 압축, 신경 열을 포함하는 블록을 읽고 데이터의 볼륨이 디스크에서 읽어 보시기 바랍니다.

    당신이 열 중심의 스토리지에 익숙하지 않은 경우, 포스트 그레스 하나의 구현 Citus 데이터에서 오는, 다른 하나는 그린 플럼, 또 다른 Paraccel는 다른 (느슨하게 말하기) 아마존 Redshift에있다. MySQL을위한 Infobright, 지금은 거의 소멸 InfiniDB이 있습니다. 다른 상용 제품은 HP에서 Vertica의, 사이베이스 IQ, 테라 데이타 포함 ...

  12. ==============================

    12.

    select * from table1 INTERSECT  select * from table2
    

    같은

    select distinct t1 from table1 where Exists (select t2 from table2 where table1.t1 = t2 )
    
  13. from https://stackoverflow.com/questions/3180375/select-vs-select-column by cc-by-sa and MIT license