codememo

MySQL은 왜 이러한 가능한 키를 사용하지 않습니까?

tipmemo 2023. 10. 5. 21:53
반응형

MySQL은 왜 이러한 가능한 키를 사용하지 않습니까?

다음과 같은 문의 사항이 있습니다.

SELECT t.id
FROM account_transaction t
JOIN transaction_code tc ON t.transaction_code_id = tc.id
JOIN account a ON t.account_number = a.account_number
GROUP BY tc.id

할 때는.EXPLAIN첫번째 행은 무엇보다도 다음을 보여줍니다.

table: t
type: ALL
possible_keys: account_id,transaction_code_id,account_transaction_transaction_code_id,account_transaction_account_number
key: NULL
rows: 465663

키가 NULL인 이유는 무엇입니까?

데이터 유형이 일치하지 않는 문제도 있을 수 있습니다.예를 들어 열이 문자열 데이터 유형(CHAR, ex의 경우)인데 쿼리가 숫자를 인용하지 않는 경우 MySQL은 인덱스를 사용하지 않습니다.

SELECT * FROM tbl WHERE col = 12345; # No index
SELECT * FROM tbl WHERE col = '12345'; # Index

출처: 오늘 이 문제와 싸웠고, MySQL 5.1에서 어려운 방법을 배웠습니다. :)

편집: 이를 확인하기 위한 추가 정보:

mysql> desc das_table \G
*************************** 1. row ***************************
  Field: das_column
   Type: varchar(32)
   Null: NO
    Key: PRI
Default: 
  Extra: 
*************************** 2. row ***************************
[SNIP!]

mysql> explain select * from das_table where das_column = 189017 \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: das_column
         type: ALL
possible_keys: PRIMARY
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 874282
        Extra: Using where
1 row in set (0.00 sec)

mysql> explain select * from das_table where das_column = '189017' \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: das_column
         type: const
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 34
          ref: const
         rows: 1
        Extra: 
1 row in set (0.00 sec)

통계가 깨졌기 때문일 수도 있고, 두 표 사이에 항상 1:1 비율이 있다는 것을 알기 때문일 수도 있습니다.

쿼리에 인덱스를 강제로 사용할 수 있으며 이를 통해 속도가 향상되는지 확인할 수 있습니다.통계가 최신 상태인지 확인하기 위해 ANALIZE TABLE을 실행합니다.

USE INDEX(index_list)를 지정하면 MySQL에서 명명된 인덱스 중 하나만 사용하여 테이블의 행을 찾도록 지정할 수 있습니다.대체 구문 IGNORGE INDEX(index_list)를 사용하여 MySQL에서 일부 특정 인덱스 또는 인덱스를 사용하지 않도록 지시할 수 있습니다.이러한 힌트는 가능한 인덱스 목록에서 MySQL이 잘못된 인덱스를 사용하고 있음을 나타내는 경우 유용합니다.

또한 USE INDEX(index_list)와 같은 역할을 하지만 테이블 스캔이 매우 비싸다고 가정하는 FORCE INDEX를 사용할 수 있습니다.즉, 테이블 검색은 테이블에서 행을 찾기 위해 지정된 인덱스 중 하나를 사용할 방법이 없는 경우에만 사용됩니다.

각 힌트에는 열 이름이 아니라 인덱스 이름이 필요합니다.Primary KEY의 이름은 Primary입니다.테이블의 인덱스 이름을 보려면 SHOW INDEX를 사용합니다.

출처: http://dev.mysql.com/doc/refman/5.1/en/index-hints.html

에 대한 색인group by(=order by)

...
GROUP BY tc.id

그룹 바이는 tc.id 에서 암묵적인 정렬을 수행합니다.
tc.id 에 가능한 키가 나열되어 있지 않습니다.
t.transaction_id is.

코드를 다음으로 변경합니다.

SELECT t.id
FROM account_transaction t
JOIN transaction_code tc ON t.transaction_code_id = tc.id
JOIN account a ON t.account_number = a.account_number
GROUP BY t.transaction_code_id

이것은 잠재적인 지수를 넣을 것입니다.transaction_code_id눈에 보이는

조인에 대한 인덱스
조인이 (거의) 세 개의 테이블에 완전히 가입하면 인덱스를 사용할 필요가 없으므로 MySQL은 그렇지 않습니다.

인덱스를 사용하지 않는 기타 이유
고려 중인 행의 큰 %(IIRC 40%)가 동일한 값으로 채워진 경우.MySQL은 인덱스를 사용하지 않습니다. (인덱스를 사용하지 않는 이 더 빠르기 때문입니다.)

언급URL : https://stackoverflow.com/questions/5719392/why-isnt-mysql-using-any-of-these-possible-keys

반응형