2012-08-10 10 views
10

tabeli:Optymalizacja zapytań SQL uniknięcia tymczasowej tabeli

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; 

zapytania:

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

wyjaśniania wynik:

  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 

Pytanie:

Jak mogę ją zoptymalizować, aby nie używać tabeli tymczasowej?

Odpowiedz

3

Jak zapewne zrozumieć, problemem jest to, że GROUP BY zamawia dane wg UserId, ale spowodowało zestaw powinien być sortowane według Created; w ten sposób MySQL umieszcza dane wyjściowe w tabeli tymczasowej, sortuje je i wyprowadza.

Sztuczka może polegać na wymuszeniu na wyjściu oddzielnych wierszy w zamówieniu Created.

Pierwszy, który przychodzi mi na myśl jest coś takiego:

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

i zmienić indeks (FriendUserId, IsDisplayed, Created, UserId).

Albo inny zapytania o tym samym indeksie:

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

MySQL documentation mówi:

tabele tymczasowe mogą być tworzone w warunkach takich jak te:

Jeśli jest ORDER BY klauzula a inny GROUP BY klauzula, czy ORDER BY lub GROUP BY zawiera kolumny z tabel innych niż pierwsza tabela w kolejce dołączania, tworzona jest tabela tymczasowa.

Tak, można uniknąć tylko przy użyciu tabeli tymczasowej wyłącznie poprzez usunięcie order by Created

Powiązane problemy