Оптимизация запросов MySQL с помощью JOIN и COUNT - PullRequest
0 голосов
/ 17 июля 2011

У меня следующий запрос MySQL:

SELECT t1.id, t1.releaseid, t1.site, t1.date, t2.pos FROM `tracers` as t1
LEFT JOIN (
    SELECT `releaseid`, `date`, COUNT(*) AS `pos` 
    FROM `tracers` GROUP BY `releaseid`
) AS t2 ON t1.releaseid = t2.releaseid AND t2.date <= t1.date 
ORDER BY `date` DESC , `pos` DESC LIMIT 0 , 100

Идея состоит в том, чтобы выбрать релиз и подсчитать, сколько других сайтов также выпустили его до указанной даты, чтобы получить позицию.

Объясните, говорит:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY t1  ALL NULL    NULL    NULL    NULL    498422  Using temporary; Using filesort
1   PRIMARY <derived2>  ALL NULL    NULL    NULL    NULL    91661    
2   DERIVED tracers index   NULL    releaseid   4   NULL    498422   

Любые предложения по устранению временного использования; Используете сортировку файлов? Это займет много времени. Индексы, о которых я подумал и попробовал, ничего не помогли.

Ответы [ 4 ]

0 голосов
/ 02 ноября 2013

Этот ответ ниже, возможно, не изменит вывод объяснения, однако, если ваша основная проблема заключается в сортировке данных, которую он идентифицировал с помощью , удаление предложения order заставит ваш запрос выполняться быстрее , попробуйте сначала отсортировать таблицу соединений подзапроса иВаш запрос будет:

SELECT t1.id, t1.releaseid, t1.site, t1.date, t2.pos FROM `tracers` as t1
LEFT JOIN (
    SELECT `releaseid`, `date`, COUNT(*) AS `pos` 
    FROM `tracers` GROUP BY `releaseid`
    ORDER BY `pos` DESC -- additional order
) AS t2 ON t1.releaseid = t2.releaseid AND t2.date <= t1.date 
ORDER BY `date` DESC , `pos` DESC LIMIT 0 , 100

Примечание. Моя версия базы данных - mysql-5.0.96-x64, возможно, в другой версии вы получите другой результат.

0 голосов
/ 17 июля 2011
  1. убедитесь, что у вас есть индекс для releaseid.
  2. переверните JOIN, подзапрос должен быть слева от JOIN.
  3. помещает предложения ORDER BY и LIMIT внутри подзапроса.
0 голосов
/ 17 июля 2011

Попробуйте использовать два индекса: один на (date) и один на (releaseid, date).

Другое дело, что ваш запрос, похоже, не выполняет то, что вы описываете.Действительно ли он считается правильно?

Попробуйте переписать его как:

SELECT t1.id, t1.releaseid, t1.site, t1.`date`
     , COUNT(*) AS pos
FROM tracers AS t1
  JOIN tracers AS t2
    ON  t2.releaseid = t1.releaseid
    AND t2.`date` <= t1.`date` 
GROUP BY t1.releaseid
ORDER BY t1.`date` DESC
       , pos DESC
LIMIT 0 , 100

или как:

SELECT t1.id, t1.releaseid, t1.site, t1.`date`
     , ( SELECT COUNT(*)
         FROM tracers AS t2
         WHERE t2.releaseid = t1.releaseid
           AND t2.`date` <= t1.`date`
       ) AS pos
FROM tracers AS t1
ORDER BY t1.`date` DESC
       , pos DESC
LIMIT 0 , 100
0 голосов
/ 17 июля 2011

Попробуйте добавить индекс на tracers.releaseid и один на tracers.date

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...