2011-05-22 16 views
5

Tabla:¿Por qué MySQL usa filesort en este caso? Estructura

CREATE TABLE IF NOT EXISTS `newsletters` 
(
    `id` int(11) NOT NULL auto_increment, 
    `last_update` int(11) default NULL, 
    `status` int(11) default '0', 
    `message_id` varchar(255) default NULL, 
    PRIMARY KEY (`id`), 
    KEY `status` (`status`), 
    KEY `message_id` (`message_id`), 
    KEY `last_update` (`last_update`) 
) 
ENGINE=MyISAM DEFAULT CHARSET=latin1; 

la consulta:

SELECT id, last_update 
FROM newsletters 
WHERE status = 1 
ORDER BY last_update DESC 
LIMIT 0, 100 
  • newsletters tabla tiene más de de 3 millones de registros
  • consulta tarda más de 26 segundos para ejecutar

de consulta a explicar:

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE newsletters range status status 5 NULL 3043354 Using where; Using filesort 

¿Por qué es que no utilizan filesort, y cómo es que una consulta range?

Respuesta

5

Está utilizando filesort para ordenar en last_update. Puede evitar el archivo que cambiando el índice a status, last_update, por lo que MySQL encuentra todas las filas con el estado 1 en el orden correcto.

Para optimizar aún más, cambie el índice a status, last_update, id. Eso permite que MySQL satisfaga la consulta simplemente mirando el índice, sin una búsqueda en la tabla.

CREATE INDEX idx_newsletters_status 
ON newsletters(status, last_update, id); 
+0

KEY debe aplicar los índices al igual que INDEX. –

+0

Eso lo hizo, soy un aficionado a la optimización/indexación, así que realmente no pensé en intentar indexar múltiples columnas. @Baez: ¿Puedes entender lo que quieres decir con eso? – HyderA

+1

@gAMBOOKa: Para visualizar qué índice lo ayudaría más, intente pensar en qué lista, en qué orden le ayudaría más si fuera la computadora, y tuviera que buscar rápidamente los registros correctos, y devolver la información solicitada . En este caso, desearía una lista de todos los registros (ya que cada índice debe ser de todos los registros) ordenados primero por estado (ya que solo le interesan los 1s), y luego por last_update (para que pueda rápidamente obtener los primeros 100 de esos). Si agrega la identificación a la lista, puede obtener toda su información sin tener que volver a la tabla principal. – Avi

Cuestiones relacionadas