«использование временных» с максимальными и минимальными запросами в mysql

У меня большая проблема с запросом, в котором мне нужно получить некоторые максимальные и минимальные значения, связанные с каждой строкой. Для упрощения этот запрос присоединяется к другой таблице, но я покажу только максимальный и минимальный запросы.

SELECT mv . * , mu . * 
FROM (

    SELECT Device_id, MAX( Last_time ) AS last_visit, 
                      MIN( Last_time ) AS first_visit
    FROM device_tracker
    GROUP BY Device_id
)mv
JOIN (
    SELECT Referral AS current_url, 
    Device_id, MAX( Last_time ) AS last_url_visit, MIN(Last_time ) AS first_url_visit
    FROM device_tracker GROUP BY Device_id, current_url) mu 
ON ( mv.Device_id = mu.Device_id )

Если я выполняю объяснение, в нем говорится, что это «первое соединение» использует временную сортировку и сортировку файлов, и это приводит к краху базы данных в этой точке, используя некоторое время ЦП почти на 100%.

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY <derived2>  ALL NULL    NULL    NULL    NULL    7275     
1   PRIMARY <derived3>  ALL NULL    NULL    NULL    NULL    15137   Using where
3   DERIVED device_tracker  index   NULL    index_api   522 NULL    28392   Using index; Using temporary; Using filesort
2   DERIVED device_tracker  range   NULL    index_api   257 NULL    7099    Using index for group-by

вопрос: есть ли способ заставить этот запрос использовать индекс, чтобы избежать временной и файловой сортировки? Заранее спасибо!!!

РЕДАКТИРОВАНИЕ: теперь проблема более сфокусирована. Если мы выполним только второй подзапрос:

EXPLAIN SELECT Referral, Device_id, MAX( Last_time ), MIN( Last_time )
FROM device_tracker
GROUP BY Device_id, Referral

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  device_tracker  index   NULL    index_api   522 NULL    28412   Using index; Using temporary; Using filesort

и мы установили эти индексы:

NAME:      TYPE:     ROWS:  FIELDS:
PRIMARY    PRIMARY   28413  id
index_api  INDEX     28413  Device_id, Last_Time, Referral

person Javi Prieto    schedule 04.04.2011    source источник
comment
Можете ли вы опубликовать структуру вашей таблицы? это может помочь увидеть индексы, в частности.   -  person Jaydee    schedule 04.04.2011
comment
@jaydee: я разместил индексы и кое-какую новую информацию. Проблема в одном из подзапросов.   -  person Javi Prieto    schedule 04.04.2011
comment
Да, кажется, вам нужен один индекс для «Device_id, Referral» и один для «Device_id».   -  person Timo    schedule 04.04.2011
comment
Да, вам нужно (Device_id, referral, Last_time). Индекс (Device_id, Last_time, referral) не поможет в этом запросе.   -  person Jaydee    schedule 05.04.2011
comment
@Jaydee: Просто извините за мое невежество, но почему это сработало? Я имею в виду, не могли бы вы объяснить, в чем разница между индексом (device_id, referral, Last_time) и (device_id, Last_time, referral) в данном случае? Большое спасибо, кстати!   -  person Javi Prieto    schedule 05.04.2011
comment
Индекс — это просто список предварительно отсортированных записей, каждая со ссылкой на запись в таблице (физически он может иметь различную структуру, но здесь это не имеет значения). Если у вас есть (Device_id,referral,Last_time), то все записи с одинаковым device_id и referral будут стоять рядом друг с другом в списке, а min и max будут первой и последней записями в каждой группе. С помощью (device_id, Last_time, referral) список группирует все одинаковые идентификаторы устройств вместе, но затем сортирует по времени, поэтому записи ссылок могут быть в любом порядке, поэтому их нельзя эффективно сгруппировать.   -  person Jaydee    schedule 05.04.2011


Ответы (1)


У вас есть индекс (device_id, Last_time) в трекере устройств? А также (Device_id,refferal,Last_time).

Индексы и GROUP BY могут иметь довольно сложные проблемы.

person Jaydee    schedule 04.04.2011