possible_keys는 mysql이 테이블에서 사용할 수 있는 인덱스 후보들을 말한다. key는 실제로 테이블을 읽을때 사용한 인덱스를 말함. 즉 중요한건 key임. 참고로 innodb는 비용기반으로 가장 적은 비용이 드는 인덱스를 후보중에서 고른다.
한편 possible_keys에 후보들이 있는데 실제로 아무런 키가 사용되지 않는 경우도 있다.
EXPLAIN SELECT * FROM product WHERE category_id > 0;

인덱스가 있어도 풀 테이블 스캔을 사용하는 이유, 어차피 읽을 행이 너무 많으면 인덱스를 통해 원 데이터를 찾아가는 과정(이 과정은 랜덤 I/O로 일어난다.)이 너무 잦아서 이 오버헤드를 줄이기 위해 그냥 처음부터 원본 데이터를 찾아가버린다. 읽어야할 행이 전체의 20~30% 이상 정도 되면 이런 전략을 택해버림. 왜? 풀테이블 스캔은 순차 I/O에 가깝기 때문. 오버헤드가 거의 없다.
한편 후보에는 없는데도 인덱스를 사용하는 케이스도 있다. 즉 possible_keys는 null인데 key에 인덱스가 잡혀있음.
EXPLAIN SELECT member_id FROM orders;

이건 옵티마이저가 커버링 인덱스를 사용할때 발생함. where절에 인덱스를 포함하지 않아서 후보키에는 인덱스가 없지만, 결국 셀렉트하는 컬럼이 전부 인덱스에 포함되어있으니, 옵티마이저가 스스로 최적화해서 그냥 인덱스만 읽자고 판단한 것임.
복합 인덱스에서 몇개 컬럼을 활용했는가를 나타낸다. 엄밀히는 사용된 인덱스 키의 바이트 길이임. 이 값을 이용해 복합 인덱스에서 몇개의 컬럼을 사용했는지 역으로 연산할 수 있다.
그런데 귀찮은건 이건 알기 위해선 데이터 타입별 바이트 크기를 대강 알고 있어야 함. 참고로 실제 담겨있는 데이터의 실제 길이는 아님. 만약 이랬다면 타입이 varchar라면 일일이 계산해야 한다. 이렇지 않고, key_len은 해당 인덱스의 데이터 타입이 가질 수 있는 최대 키 길이를 기준으로 계산된다.
여기에는 다음의 규칙이 있다.

vachar는 다음의 규칙을 따른다.
vacher(n)일 경우, 4 * n + 2