2012-08-10 22 views
10

La Tabla:optimización de consultas SQL para evitar la tabla temporal

CREATE TABLE `T1` (
    `UserId` int(10) unsigned NOT NULL, 
    `FriendUserId` int(10) unsigned NOT NULL, 
    `IsDisplayed` tinyint(1) unsigned NOT NULL, 
    `Created` datetime NOT NULL, 
    KEY `FriendUserId` (`FriendUserId`,`IsDisplayed`,`UserId`,`Created`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

la consulta:

SELECT `UserId`, `FriendUserId`, UNIX_TIMESTAMP(`Created`) AS `Created` 
FROM `T1` WHERE `FriendUserId` = 22 
    AND `IsDisplayed` = 0 
    GROUP BY `UserId` 
    ORDER BY `Created` 

EXPLIQUE resultado:

  id: 1 
    select_type: SIMPLE 
     table: T1 
     type: ref 
possible_keys: FriendUserId 
      key: FriendUserId 
     key_len: 5 
      ref: const,const 
     rows: 1 
     Extra: Using where; Using index; Using temporary; Using filesort 

Pregunta:

¿Cómo puedo optimizarlo para que no se use una tabla temporal?

Respuesta

3

Como podrán comprender, el problema es que GROUP BY ordena los datos por UserId, pero el conjunto resultado debe ser ordenada por Created; por lo tanto, MySQL coloca la salida en una tabla temporal, la ordena y genera.

El truco podría ser forzar la salida de distintas filas en el orden Created a la vez.

El primero que viene a la mente es algo como esto:

SELECT DISTINCT 
    UserId, 
    FriendUserId, 
    UNIX_TIMESTAMP(`Created`) AS `Created` 
FROM T1 
WHERE FriendUserId = 22 AND IsDisplayed = 0 
ORDER BY `Created` 

y cambiar el índice de (FriendUserId, IsDisplayed, Created, UserId).

O otra consulta con el mismo índice:

SELECT 
    UserId, 
    FriendUserId, 
    UNIX_TIMESTAMP(`Created`) AS `Created` 
FROM T1 
WHERE FriendUserId = 22 AND IsDisplayed = 0 
GROUP BY `Created`, UserId 
9

MySQL documentation dice:

Las tablas temporales se pueden crear en condiciones como éstas:

Si hay un ORDER BY cláusula y una GROUP BY cláusula diferente, o si el ORDER BY o GROUP BY contiene columnas desde tablas que no sean la primera tabla en la cola de unión, se crea una tabla temporal.

Por lo tanto, sólo se puede evitar el uso de la tabla temporal sólo eliminando la order by Created

Cuestiones relacionadas