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가 쿼리를 최적화하는 데 사용할 수있는 더 많은 정보를 제공하고 스키마 변경 등에 대해 코드에서 더 나은 제어를 제공합니다.
SELECT쿼리가 실행 / 처리 데이터베이스에서 데이터베이스에 다릅니다.