FORCE INDEX

Los index hints (FORCE INDEX, USE INDEX, IGNORE INDEX) permiten influir en la decisión del optimizador sobre qué índice usar. El optimizador de MySQL generalmente elige bien, pero en algunos casos puedes obtener mejor rendimiento forzando un índice específico.

Sintaxis

-- Forzar un índice
SELECT * FROM tabla FORCE INDEX (nombre_indice) WHERE condicion;
 
-- Sugerir un índice
SELECT * FROM tabla USE INDEX (nombre_indice) WHERE condicion;
 
-- Ignorar un índice
SELECT * FROM tabla IGNORE INDEX (nombre_indice) WHERE condicion;

Diferencia entre FORCE, USE e IGNORE

HintComportamiento
USE INDEXSugiere índices. Si ninguno sirve, hace full table scan
FORCE INDEXFuerza el uso de índices. Solo hace scan si ningún índice funciona
IGNORE INDEXExcluye índices específicos de la consideración

Ejemplo con USE INDEX

-- Crear dos índices en pedidos
CREATE INDEX idx_estado ON pedidos (estado);
CREATE INDEX idx_fecha ON pedidos (fecha_pedido);
 
-- Sin hint: MySQL elige el índice
EXPLAIN SELECT * FROM pedidos
WHERE estado = 'pendiente' AND fecha_pedido > '2025-12-01';
idselect_typetabletypepossible_keyskeyrowsExtra
1SIMPLEpedidosrefidx_estado,idx_fechaidx_estado7Using where
-- Sugerir que use el índice de fecha
EXPLAIN SELECT * FROM pedidos USE INDEX (idx_fecha)
WHERE estado = 'pendiente' AND fecha_pedido > '2025-12-01';
idselect_typetabletypepossible_keyskeyrowsExtra
1SIMPLEpedidosrangeidx_fechaidx_fecha10Using index condition; Using where

Ejemplo con FORCE INDEX

-- FORCE INDEX para obligar a usar un índice específico
EXPLAIN SELECT * FROM pedidos FORCE INDEX (idx_fecha)
WHERE estado = 'pendiente' AND fecha_pedido > '2025-12-01';
idselect_typetabletypepossible_keyskeyrowsExtra
1SIMPLEpedidosrangeidx_fechaidx_fecha10Using index condition; Using where

La diferencia con USE INDEX: si el índice sugerido no es aplicable, USE INDEX permite un full scan, mientras que FORCE INDEX intenta con más fuerza usar el índice antes de recurrir al scan.

Ejemplo con IGNORE INDEX

-- Ignorar un índice para que MySQL elija otro
EXPLAIN SELECT * FROM pedidos IGNORE INDEX (idx_estado)
WHERE estado = 'pendiente' AND fecha_pedido > '2025-12-01';
idselect_typetabletypepossible_keyskeyrowsExtra
1SIMPLEpedidosrangeidx_fechaidx_fecha10Using index condition; Using where

Al ignorar idx_estado, MySQL usa idx_fecha.

Hints para operaciones específicas

Puedes especificar para qué operación aplica el hint:

-- Solo para JOIN
SELECT * FROM pedidos FORCE INDEX FOR JOIN (idx_fecha)
JOIN clientes ON pedidos.cliente_id = clientes.id;
 
-- Solo para ORDER BY
SELECT * FROM pedidos FORCE INDEX FOR ORDER BY (idx_fecha)
ORDER BY fecha_pedido;
 
-- Solo para GROUP BY
SELECT estado, COUNT(*) FROM pedidos FORCE INDEX FOR GROUP BY (idx_estado)
GROUP BY estado;

Múltiples índices

Puedes especificar varios índices en un hint:

-- Sugerir múltiples índices
SELECT * FROM pedidos USE INDEX (idx_estado, idx_fecha)
WHERE estado = 'pendiente' AND fecha_pedido > '2025-12-01';
 
-- Ignorar múltiples índices
SELECT * FROM pedidos IGNORE INDEX (idx_estado, idx_fecha)
WHERE estado = 'pendiente';

Cuándo usar index hints

Los index hints son una herramienta de último recurso. Úsalos solo cuando:

  1. El optimizador elige mal: Has verificado con EXPLAIN que el plan es subóptimo
  2. ANALYZE TABLE no ayuda: Las estadísticas están actualizadas pero el optimizador sigue eligiendo mal
  3. La diferencia es significativa: El plan alternativo es notablemente más rápido

No usar index hints cuando:

  • No has analizado el plan actual con EXPLAIN
  • La tabla es pequeña (el optimizador rara vez se equivoca)
  • Acoplarías la consulta a un índice que podría cambiar

Desventajas

ProblemaDescripción
FragilidadSi el índice cambia de nombre o se elimina, la consulta falla
MantenimientoLos hints se vuelven obsoletos si los datos cambian
RigidezEl optimizador no puede adaptarse a cambios en los datos

Limpieza

DROP INDEX idx_estado ON pedidos;
DROP INDEX idx_fecha ON pedidos;

En el siguiente artículo veremos la optimización IS NULL, que explica cómo MySQL maneja las comparaciones con NULL en los índices.

Escrito por Eduardo Lázaro