SELECT *가 SELECT foo보다 크기가 빠른 이유는 무엇입니까?


28

다음과 같이 값과 해시 테이블을 고려하십시오.

+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| val        | char(9)  | NO   |     | NULL    |                |
| val_hashed | char(50) | YES  |     | NULL    |                |
+------------+----------+------+-----+---------+----------------+

다음 쿼리는 0.00 초 후에 완료됩니다.

SELECT * FROM hashes ORDER BY 1 DESC LIMIT 1;

그러나이 쿼리는 3 분 17 초가 걸립니다.

SELECT val FROM hashes ORDER BY 1 DESC LIMIT 1;

쿼리가 실행되는 동안 프로세스 목록에 상태가 표시 Sorting result됩니다. 상황은 완전히 재현 가능합니다. INSERT테이블에서 작업을 지속적으로 수행하는 다른 프로세스가 있습니다.

더 구체적인 쿼리가 *쿼리 보다 실행하는 데 더 오래 걸리는 이유는 무엇 입니까? 나는 항상 *성능상의 이유로 쿼리를 피해야 한다고 믿었습니다 .


7
첫 번째 명령문은 대부분 기본 키 인덱스를 사용 id하여 첫 번째 행을 찾습니다. 두 번째는 (인덱싱되지 않은) val열 에서 전체 결과를 정렬해야합니다 .
a_horse_with_no_name

8
ORDER BY NUMBER구문은 매우 발생하기 쉬운 오류입니다.
usr

2
마지막 코멘트에 추가 SELECT *의 열 인덱스와 결합하는 것은 ORDER BY방지 할 수있는 또 다른 이유 - 분류되는 열 난독이다 *의 ...
LC.

@lc., 무슨 뜻인가요?
Pacerier

@Pacerier 나는 *명시 적이 지 않다는 것을 의미한다 . 그래서 "모든 열을주고 세 번째 열을 기준으로 정렬"이라고 말하는 것은 "슈퍼마켓으로 가서 몇 개의 신호등을 통과했는지 알려주는 것"과 같이 결정 론적
입니다.

답변:


33

문구 ORDER BY 1는 다른 열을 나타냅니다. 첫 번째 id는 두 번째 val입니다. id열쇠 이기 때문에 색인이 생성되고 order by사소한 일이 될 것입니다. 하는 방법은 order by val, 그러나, 시스템은 모든 행, 정렬 전체 테이블을 검색해야합니다 val다음 해당 행 하나를 선택합니다.

두 쿼리를 모두 변경하면 order by id실행 시간이 거의 동일하다고 생각합니다.


3
때때로 가장 까다로운 질문은 우리를 얼굴로 쳐다 보는 것입니다. 고마워, 마이클!
dotancohen

7

쿼리의 성능 차이는 MG에 의해 잘 설명되어 있습니다. 이 문제를 해결하려고합니다.

나는 항상 성능상의 이유로 쿼리를 피해야한다고 항상 믿었다.

select *그 자체로는 특별한 처벌이 없으며 잘못 사용하면 문제가됩니다. 단일 테이블 쿼리에서는 잘 작동합니다. 이제 해당 테이블을 20 개의 열이있는 다른 테이블에 조인하고 나중에 여러 개의 열이있는 5 개의 다른 테이블에 조인을 추가합니다. 이제 문제입니다. 따라서 광범위한 반창고를 가르치는 사람들은 이유를 설명하지 않고 "X를 절대하지 마십시오".


3
SELECT *단일 테이블 쿼리에서도 문제가 될 수 있습니다. 예를 들어, SELECT * FROM hashes ORDER BY val;전체 테이블 스캔을 수행 한 후 정렬하는 동안 SELECT val FROM hashes ORDER BY val;전체 인덱스 스캔 만 수행 하고 정렬 은 수행하지 않습니다 (인덱스가 val에 있다고 가정). 따라서 우리가 필요한 결과 만 선택하는 것은 결코 아프지 않습니다.
ypercubeᵀᴹ

나는 당신이 이것을 본 것으로 가정합니까? sqlblog.com/blogs/aaron_bertrand/archive/2009/10/10/…
최대 버논

@ypercube, 하위 선택select(*) 으로 만 사용되는 경우에도 발생합니까 ? 임베디드 선택이기 때문에 MySQL이 선택 해야하는 실제 열을 파악할만큼 똑똑하지 않습니까?
Pacerier

@Pacerier mysql 옵티마이 저는 사용중인 버전에 따라 다른 수준의 "스마트 니스"를 갖습니다. gerneal에서는 중첩 된 하위 쿼리와 관련하여 꽤 바보 였으므로 그를 도울 수있는 모든 것이 좋았습니다.
ypercubeᵀᴹ

@ypercube, Ah, pgsql만큼이나 똑똑하다면.
Pacerier
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.