SQL SELECT 속도 int 대 varchar


110

나는 테이블을 만드는 과정에 있는데 그것은 나를 놀라게했다.

제조사 (fx BMW, Audi 등)가있는 자동차를 저장하면 make를 int 또는 varchar로 저장하면 쿼리 속도에 차이가 생길 수 있습니다.

그래서

SELECT * FROM table WHERE make = 5 AND ...;

보다 빠름 / 느림

SELECT * FROM table WHERE make = 'audi' AND ...;

아니면 속도가 어느 정도 같을까요?

답변:


99

int가 varchar보다 훨씬 적은 공간을 차지한다는 단순한 사실 때문에 Int 비교는 varchar 비교보다 빠릅니다.

이는 인덱싱되지 않은 액세스와 인덱싱 된 액세스 모두에 적용됩니다. 가장 빠른 방법은 인덱싱 된 int 열입니다.


postgreql 질문에 태그를 지정했듯이 다양한 날짜 유형의 공간 사용량에 관심이있을 수 있습니다.


13
7.4 페이지를 참조하고 있습니다. 최신 버전에서는 <126 바이트 인 경우 1 바이트 + 길이를 차지합니다. 또한 문자열이 훨씬 느린 이유는 문자열이 더 많은 공간을 차지하는 것이 아니라 데이터 정렬에 민감한 비교가 매우 비싸기 때문입니다. 그러나 최종 결과는 물론 동일합니다.
Magnus Hagander

@Magnus-주의 해 주셔서 감사합니다. 담당자 점수가 충분하므로 내 대답을 자유롭게 편집하십시오.
Robert Munteanu

"문자열이 더 많은 공간을 차지한다는 것은 아닙니다."... 최소 크기 이상의 문자열은 고정밀 숫자보다 훨씬 더 많은 공간을 차지합니다. 숫자 (단수)에는 고정 단위가 있기 때문에 문자열은 항상 집계 유형입니다. . 64 비트 숫자의 경우 8 바이트 길이 바이트 또는 구조체를 포함하여 문자열에서 문자 당 4 바이트; 또는 믿을 수 없을 정도로 순진한 구현을위한 또 다른 종결 문자 ...
MrMesees

@RobertMunteanu 안녕하세요 Robert, 죄송하지만 이것이 오래된 게시물이라는 것을 알고 있지만 다음 사항을 친절하게 확인할 수 있습니다. 정수를 쿼리하려면 각 문자열 열을 다른 테이블 (관계)에 연결해야합니다. 그러나 이는 각 쿼리에 더 많은 조인 작업이 필요함을 의미합니다. 이 절충안이 그만한 가치가 있는지 어떻게 알 수 있습니까? 감사합니다!
AiRiFiEd

2
"int 비교가 varchar 비교보다 빠릅니다. int가 varchar보다 훨씬 적은 공간을 차지한다는 단순한 사실 때문입니다."-이것은 일반적으로 사실이 아닙니다 . 사용하는 DBMS와 삽입하려는 정확한 데이터 유형 및 문자열에 따라 8 바이트 정수가 평균 길이 3-4 자의 일부 텍스트 ID를 보유하는 ascii varchar보다 길 수 있습니다. 따라서이 답변은 부정확하고 특정 맥락이나 실험적 결과가 부족한 것이 실제로 질문에 대한 답변이 아닙니다. varchars가 int보다 훨씬 더 많은 공간을 차지할 있다는 것을 누구나 알고 있지만 그럴 필요는 없습니다.
Marcin Wojnarski 2019

36

몇 가지 대략적인 벤치 마크 :

Postgres 9.x의 4 백만 레코드

Table A = base table with some columns
Table B = Table A + extra column id of type bigint with random numbers
Table C = Table A + extra column id of type text with random 16-char ASCII strings

8GB RAM, i7, SSD 노트북의 결과 :

Size on disk:                A=261MB        B=292MB        C=322MB
Non-indexed by id: select count(*), select by id: 450ms same on all tables
Insert* one row per TX:       B=9ms/record        C=9ms/record
Bulk insert* in single TX:    B=140usec/record    C=180usec/record
Indexed by id, select by id:  B=about 200us       C=about 200us

* inserts to the table already containing 4M records

따라서 인덱스가 RAM에 맞는 한, bigint 대 16-char 텍스트는 속도에 차이가 없습니다.


6
매우 흥미로운. 차이가 무시할만한 이유는 무엇입니까?
Chibueze Opata 17.09.09

18

varchar 대신 int를 사용하면 조금 더 빠를 것입니다. 속도를 위해 더 중요한 것은 쿼리가 레코드를 찾는 데 사용할 수있는 필드에 대한 인덱스를 갖는 것입니다.

int를 사용하는 또 다른 이유는 데이터베이스를 정규화하는 것입니다. 'Mercedes-Benz'라는 텍스트를 테이블에 수천 번 저장하는 대신 ID를 저장하고 브랜드 이름을 별도의 테이블에 한 번 저장해야합니다.


더 설명해 주시겠습니까? 대신의 뜻 Mercedes-Benz배 아이디의 저장 수천 1. 예를 들어 테이블 car_brands, 열 BrandsId. 행 Mercedes-Benz1. 그리고 기본 테이블 열과 Brands1. 그리고 때 SELECT, 그때 처음 얻을 Id테이블에서 car_brands다음과 SELECT Something FROM main_table WHERE Brands = (SELECT Id FROM car_brands WHERE Brands = Mercedes-Benz). 아니면 다른 접근 방식?
안드리

3
@ user2118559 : 예, 저장하는 방법입니다. 데이터를 얻으려면 일반적으로 하위 쿼리 대신 조인을 사용합니다 select something from main_table c inner join car_brands b on b.Id = c.Brands where b.Brands = 'Mercedes-Benz'..
Guffa

왜 반대 투표입니까? 자신이 틀렸다고 생각하는 것이 무엇인지 설명하지 않으면 답을 개선 할 수 없습니다.
Guffa

8

문자열 비교와 non-floats의 실제 성능으로 분류하면이 경우 부호없는 크기와 부호있는 크기는 중요하지 않습니다. 크기는 실제로 성능의 진정한 차이입니다. 1 바이트 + (최대 126 바이트) 대 1,2,4 또는 8 바이트 비교 ... 분명히 non-float는 문자열 및 부동 소수점보다 작기 때문에 어셈블리에서 CPU 친화적입니다.

모두 에서 문자열 대 문자열 비교 언어의 는 CPU에 의해 하나의 명령어로 비교할 수있는 것보다 느립니다. 32 비트 CPU에서 8 바이트 (64 비트)를 비교해도 VARCHAR (2) 이상보다 빠릅니다. * 다시, 생산 된 어셈블리를 보면 (손으로도) 1-8 바이트 CPU 숫자보다 char별로 char을 비교하는 데 더 많은 명령이 필요합니다.

이제 얼마나 빨라 졌습니까? 데이터의 양에 따라 달라집니다. 5를 단순히 'audi'와 비교하는 경우-이것이 DB에있는 모든 것이므로 그 결과 차이가 너무 작아서 결코 볼 수 없습니다. CPU, 구현 (클라이언트 / 서버, 웹 / 스크립트 등)에 따라 DB 서버에서 수백 번 비교 (눈에 띄기 전에 수천 번 비교) 할 때까지 볼 수 없을 것입니다.

  • 해시 비교에 대한 잘못된 분쟁을 무효화합니다. 대부분의 해싱 알고리즘 자체는 느리기 때문에 CRC64 이하와 같은 것의 이점을 얻지 못합니다. 12 년 넘게 여러 국가의 검색 엔진을위한 검색 알고리즘을 개발했고 신용 조사 기관을위한 7 년을 개발했습니다. 전화 번호, 우편 번호, 심지어 통화 * 1000 (저장) 통화 div 1000 (검색)은 비교를 위해 DECIMAL보다 빠릅니다.

오즈


6

인덱스 여부에 관계없이 int는 훨씬 빠릅니다 (varchar가 길수록 느려집니다).

또 다른 이유 : varchar 필드의 인덱스가 int보다 훨씬 큽니다. 더 큰 테이블의 경우 수백 메가 바이트 (및 수천 페이지)를 의미 할 수 있습니다. 인덱스 읽기만으로는 많은 디스크 읽기가 필요하므로 성능이 훨씬 나빠집니다.


3
예를 들어 5 백만 개의 "audi"레코드의 경우 인덱스는 "audi"문자열의 복사본 하나와 primary_key의 정수 5 백만 개만 보유하지 않을까요? 크기 차이가 실제로 그렇게 클까요? vchar 또는 정수입니까?
lulalala

당신은 옳은 lulalala이지만 임의의 문자열을 포함 할 열의 경우 대답은 충분히 공평합니다.
Awais fiaz

4

일반적으로 int는 더 빠릅니다. varchar가 길수록 느려집니다.


3

힌트 : 필드에 사용할 수있는 값 경우 make가 됩니다 결코 (또는 거의) 변화, 당신은 타협으로 ENUM을 사용할 수 있습니다. 그것은 좋은 속도와 좋은 가독성을 결합합니다.


1
흥미롭게도 ENUM과 int의 속도 차이는 어떻습니까?
googletorp

PostgresSQL에 enum데이터 유형이 있습니까? 나는 MySQL에 특정한 것이지만.
Robert Munteanu

Postgres에는 ENUM이 있지만 MySQL과 동일한 방식으로 구현되었다고 생각하지 않습니다. postgresql.org/docs/current/static/datatype-enum.html
googletorp

2
성능면에서 ENUM은 검색 필드의 int와 거의 동일하지만 대상 목록의 varchar와 비슷해야합니다 (int뿐만 아니라 일치하는 행에 대해 전체 문자열을 클라이언트로 전송해야하기 때문)
Magnus Hagander

1
여기 MySQL에서 enum을 사용하지 않는 이유에 대한 흥미로운 읽기 (불에 연료를 추가하기 위해 : D)
Wilt

1

두 필드 중 하나 에서 인덱싱 을 켜면 더 빨라집니다. 귀하의 질문에 관해서 intvarchar.


0

다소 상대적입니다. 예, INT는 더 빠를 것이지만 문제는 귀하의 상황에서 눈에 띄는 지 여부입니다. VARCHAR은 작은 단어입니까, 아니면 긴 텍스트입니까? 테이블에 몇 개의 행이 있습니까? 행이 몇 개만있는 경우 (자주 요청하는 경우) 메모리에 완전히 버퍼링 될 가능성이 큽니다.이 경우 큰 차이를 느끼지 못할 것입니다. 물론 인덱싱이 있는데, 이는 테이블이 커지면 더 중요해집니다. 최적화 된 쿼리로 SSD를 사용하는 것이 HD보다 빠를 수 있습니다. 또한 좋은 디스크 컨트롤러를 사용하면 쿼리 속도가 10 배를 초과하는 경우가 있습니다. 이것은 쿼리를 더 쉽게 읽고 쓸 수있게하고 (복잡한 조인을 작성할 필요가 없음) 개발 속도를 높이는 VARCHAR를 사용할 여지를 남겨 둘 수 있습니다. 그러나 순수 주의자들은 동의하지 않고 항상 모든 것을 정상화합니다.

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