Não sei por que, mas adicionar uma cláusula order by e limit à consulta parece sempre resultar em uma ocorrência de índice e é executada em alguns milissegundos em vez de alguns segundos.
explain select * from geo_ip where 2393196360 between start_ip and end_ip order by start_ip desc limit 1;
+----+-------------+--------+-------+-----------------+----------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+-------+-----------------+----------+---------+------+--------+-------------+
| 1 | SIMPLE | geo_ip | range | start_ip,end_ip | start_ip | 4 | NULL | 975222 | Using where |
+----+-------------+--------+-------+-----------------+----------+---------+------+--------+-------------+
Isso é bom o suficiente para mim agora, embora eu adoraria saber o motivo pelo qual o otimizador decide não usar o índice no outro caso.