부울 필드를 인덱싱 할 때 성능이 향상됩니까?


103

.NET Framework를 포함하는 쿼리를 작성하려고합니다 WHERE isok=1. 이름에서 알 수 있듯이 isok는 부울 필드 (실제로는 TINYINT(1) UNSIGNED필요에 따라 0 또는 1로 설정 됨)입니다.

이 필드를 인덱싱 할 때 성능상의 이점이 있습니까? 엔진 (이 경우 InnoDB)이 인덱스 조회 성능이 더 좋거나 나쁠까요?


답변:


80

별로. 책처럼 생각해야합니다. 책에 3 가지 종류의 단어 만 있고 모든 단어를 색인화하면 일반 페이지와 동일한 수의 색인 페이지를 갖게됩니다.

한 값의 레코드가 비교적 적 으면 성능이 향상됩니다. 예를 들어 1000 개의 레코드가 있고 그중 10 개가 TRUE 인 경우 다음을 사용하여 검색하면 유용합니다.isok = 1

Michael Durrant가 언급했듯이 쓰기 속도도 느려집니다.

편집 : 가능한 중복 : 부울 필드 인덱싱

여기에서는 인덱스가 있어도 레코드가 너무 많으면 인덱스를 사용하지 않는다는 것을 설명합니다. MySQL은 = 1을 확인할 때 인덱스를 사용하지 않지만 = 0으로 사용합니다.


4
"예 : 2-아니오 : 1"처럼 보입니다. 여기 누군가 틀 렸는데 누구 요?
Niet the Dark Absol

4
색인이 없으면 mySql은 관련 행을 찾기 위해 전체 테이블을 스캔해야합니다.
ilanco

4
그렇지 않으면 전체 인덱스를 스캔합니다. (대부분의 경우와 동일)
Michael Koper

1
차이를 만들 수 있습니다. 인덱스를 추가하는 것만으로 쿼리의 실행 시간을 절반으로 단축 할 수 있으며 쓰기는 드물고 비용이 많이 들기 때문에 패널티에 대해 신경 쓰지 않습니다. 모든과 마찬가지로, (당신이 논리적으로 그들에게 기대 것 같은 데이터베이스는 항상 실제로 작동하지 않습니다도 있기 때문에), 측정을 가정하지 마십시오
Eelco

6
이것은 TRUE와 FALSE 사이에 동일한 분포를 가정합니다. 아래 @oucil에서 언급했듯이 매우 드문 부울 값을 찾고 있다면 여전히 시간이 걸릴 수 있습니다. 항상 인덱싱해야한다는 것은 아니지만 대부분의 데이터베이스 엔진에서 데이터와 쿼리의 특성이 중요하다고 가정합니다.
mahemoff

118

내 경험상 이와 같은 질문을 보는 사람들은 우리와 같은 보트에 있기 때문에 여기에 몇 가지 다른 답변에 대해 더 세밀하게 설명하기 위해 부울 필드를 인덱싱하는 것이 무의미하다고 들었습니다.

약 4 백만 개의 행이있는 테이블이 있는데 한 번에 약 1000 개 정도만 부울 스위치에 플래그가 지정됩니다. 이것이 우리가 검색하는 대상입니다. Boolean 필드에 인덱스를 추가하면 쿼리 속도가 몇 배나 빨라졌으며 약 9 초 이상에서 1 초 미만으로 단축되었습니다.


예, 사물의 '이유'를 확실히 이해하려고 노력해야하지만, 항상 실제 데이터 세트와 함께 측정하고 다른 것을 시도하여 이론이 db 엔진의 실제 동작과 일치하는지 확인하십시오 (놀랄 것입니다 ... )
Eelco 2015 년

8
@Eelco 맞습니다.하지만이 경우 결과는 실제로 기본 이론과 잘 일치합니다. 무시할 수 있어야한다는 기본 아이디어는 검색과 일치하는 항목을 찾을 가능성이 약 50 % 인 경우에만 의미가 있습니다. 그런 다음 100 개의 일치 항목을 찾으려면 DB에서 200 개의 항목을 반복해야합니다. 그러나 항목이 시간의 1 % 만 일치하는 경우 10,000 개의 항목을 반복해야합니다.
mahemoff

7
사람들이 실제로 현장에서 시도하고 단순히 철학적 인 것보다 성능 향상 피드백을 제공하는 것이 좋습니다.
빅토르 Joras

WHERE my_col > 0 대신에 my_col = 1또한 도움 속도에 보인다
아론

28

실제 쿼리와 인덱스 / 쿼리 조합의 선택성에 따라 다릅니다.

사례 A : 조건 WHERE isok = 1및 다른 항목 없음 :

SELECT *
FROM tableX
WHERE isok = 1
  • 인덱스가 충분히 선택적인 경우 (예 : 1M 행이 있고 1k 만있는 경우 isok = 1) SQL 엔진은 인덱스를 사용하고 인덱스 가없는 경우보다 빠릅니다.

  • 인덱스가 충분히 선택적이지 않은 경우 (예 : 1M 행이 있고 100k 이상이 있음 isok = 1) SQL 엔진은 인덱스를 사용 하지 않고 테이블 스캔을 수행합니다.

사례 B : 상태 WHERE isok = 1및 기타 사항 :

SELECT *
FROM tableX
WHERE isok = 1
  AND another_column = 17

그런 다음 보유한 다른 색인에 따라 다릅니다. 인덱스 는 가능한 값이 두 개 뿐인 another_column인덱스보다 더 선택적 일 수 있습니다 isok. (another_column, isok)또는 (isok, another_column)더 나은 인덱스입니다 .


나는 이것이 상위에 비해 더 정답이라고 생각합니다. 또한 데이터의 분포.
tyan

12

데이터 분포에 따라 다릅니다.

1000 페이지가 밀집된 책이 있는데 내 책의 유일한 단어는 '예'와 '아니오'가 계속 반복되고 무작위로 배포되었다고 가정 해보십시오. '예'의 모든 항목에 동그라미 표시를하도록 요청받은 경우 책 뒷면의 색인이 도움이 될까요? 때에 따라 다르지.

예와 아니오가 반반 씩 무작위로 분포되어 있다면 색인에서 조회하는 것이 도움이되지 않습니다. 색인은 책을 훨씬 더 크게 만들 것이고, 어쨌든 나는 각 항목을 찾는 것보다 앞면에서 시작하여 각 페이지를 통해 모든 '예'인스턴스를 찾아서 동그라미를 치는 것이 더 빠를 것입니다. 색인을 작성한 다음 색인 항목에서 참조하는 페이지에 대한 참조를 가져옵니다.

하지만 예를 들어 천 페이지의 책에 '예'가 10 개만 있고 나머지는 모두 수백만 개에 불과했다면 색인을 사용하면 '예'의 10 개 인스턴스를 찾아 그 주위를 돌릴 때 많은 시간을 절약 할 수 있습니다. .

데이터베이스에서도 마찬가지입니다. 50:50 배포 인 경우 인덱스가 도움이되지 않습니다. 데이터베이스 엔진은 처음부터 끝까지 데이터를 훑어 보는 것이 더 낫습니다 (전체 테이블 스캔), 인덱스는 데이터베이스를 더 크게 만들뿐입니다. 쓰기 및 업데이트 속도가 느립니다. 그러나 4000 : 1 배포와 같은 경우 ( 이 스레드의 oucil 에 따라), 찾고있는 항목이 4000 개 중 1 개이면 인덱스 검색이 속도를 크게 높일 수 있습니다.


5

아니요, 보통은 아닙니다.

일반적으로 선택성 / 카디널리티가 높을 때 검색을 위해 필드를 인덱싱합니다. 부울 필드의 카디널리티는 대부분의 테이블에서 매우 낮습니다. 또한 쓰기 속도가 약간 느려집니다.


3

실제로 이것은 실행하는 쿼리에 따라 다릅니다. 그러나 일반적으로 그렇습니다. 또한 다른 유형의 필드를 인덱싱합니다.


2

예, 인덱스는 성능을 향상시키고 인덱스가 있거나없는 EXPLAIN의 출력을 확인합니다.

문서에서 :

인덱스는 특정 열 값이있는 행을 빠르게 찾는 데 사용됩니다. 인덱스가 없으면 MySQL은 첫 번째 행으로 시작한 다음 전체 테이블을 읽어 관련 행을 찾아야합니다. 테이블이 클수록 비용이 많이 듭니다. 테이블에 해당 열에 대한 인덱스가있는 경우 MySQL은 모든 데이터를 볼 필요없이 데이터 파일 중간에서 찾을 위치를 신속하게 결정할 수 있습니다.

나는 인덱스가되지 않습니다 말을하는 것이 안전하다고 생각 감소 당신은 단지 그것으로부터 이득 그래서,이 경우 성능.


2
인덱스는 하드 디스크에 많은 데이터를 제공하고 쓰기 속도를 느리게 만들어서 얻는 것이 아닙니다.
Michael Koper

1
사실이지만이 경우 TINYINT(1) UNSIGNED열은 데이터 크기가 작습니다.
ilanco

그리고 아마 꽤 낮은 오버 헤드 추가 쓰기
Eelco

인덱스 필드의 크기뿐만 아니라 가리키는 행 수에 따라 인덱스 크기가 커지지 않습니까?
poolie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.