O InnoDB armazena MEDIUMINT como um valor de três bytes. Mas quando o MySQL tem que fazer qualquer cálculo, os três bytes MEDIUMINT são convertidos em oito bytes unsigned long int (presumo que ninguém execute o MySQL em 32 bits hoje em dia).
Existem prós e contras, mas você entende que o raciocínio "É burro, é lento e o código que o implementa é um horror rastejante" não é técnico, certo?
Eu diria que MEDIUMINT faz sentido quando o tamanho dos dados no disco é crítico. Ou seja quando uma tabela tem tantos registros que mesmo uma diferença de byte (4 bytes INT vs 3 bytes MEDIUMINT) significa muito. É um caso bastante raro, mas possível.
mach_read_from_3 e mach_read_from_4 - primitivos que o InnoDB usa para ler números de registros InnoDB são semelhantes. Ambos retornam ulint. Aposto que você não notará diferença em qualquer carga de trabalho.
Basta dar uma olhada no código:
ulint
mach_read_from_3(
/*=============*/
const byte* b) /*!< in: pointer to 3 bytes */
{
ut_ad(b);
return( ((ulint)(b[0]) << 16)
| ((ulint)(b[1]) << 8)
| (ulint)(b[2])
);
}
Você acha que é muito mais lento do que isso?
ulint
mach_read_from_4(
/*=============*/
const byte* b) /*!< in: pointer to four bytes */
{
ut_ad(b);
return( ((ulint)(b[0]) << 24)
| ((ulint)(b[1]) << 16)
| ((ulint)(b[2]) << 8)
| (ulint)(b[3])
);
}