Этот запрос выполняется в 30-х годах. Как я могу оптимизировать это? - PullRequest
1 голос
/ 03 августа 2011

В качестве продолжения моего предыдущего вопроса здесь: Ссылка

Это мои таблицы:

-----------------------------------
ID | ChapterNo | HitCount |  MID
-----------------------------------
1  |    2      |   1000   |   1
2  |    2      |   2000   |   1
3  |    1      |   3000   |   1
4  |    3      |   1000   |   1
5  |    1      |   3500   |   1
-----------------------------------

для архивации результата, я попытался использоватьff query:

SELECT t1.id, t1.hitcount, t1.chapterno
    FROM chapter as t1
    WHERE t1.hitcount = (select max(hitcount) from chapter where chapterno = t1.chapterno and `mid` = t1.`mid`)
    AND t1.`mid` = '2524'
    ORDER BY t1.chapterno DESC

ID | ChapterNo | HitCount |  
---------------------------
4  |    3      |   1000   |
2  |    2      |   2000   |
5  |    1      |   3500   |
---------------------------

Похоже, этот запрос поначалу работает очень хорошо, но в масштабе, после того как я импортирую 80 000 записей для тестирования и реализации.Я узнаю, что это длилось 30 секунд.Объяснение показывает:

sel_type  table      type   posible_key  key       keyLen   ref        rows        Extra
PRIMARY   t1         ref    mid_idx      mid_idx    8       const      *3289*    Using where; Using filesort
PRIMARY   chapter    ref    mid_idx      mid_idx    8       m.t1.mid   *17*      Using where; Using temporary; Using filesort

Результирующий набор состоит из 640 строк.Есть ли действительно хороший способ оптимизировать это для больших таблиц?Поскольку эта таблица и особенно этот запрос будет расти больше в будущем.

Поможет ли использование процедуры в mysql для этого запроса?

Большое спасибо

Ответы [ 5 ]

3 голосов
/ 03 августа 2011

Попробуйте:

SELECT a.id, X.chapterno, X.mid, X.hitcount
FROM 
(select chapterno,  max(hitcount) as hitcount 
from chapter    
WHERE mid = 2524
group by chapterno)X
INNER JOIN chapter a ON (a.chapterno = X.chapterno AND a.mid=X.mid)
ORDER BY X.chapterno DESC

Для этого запроса будет использоваться индекс по (chapterno,hitcount).Кроме того, из ваших данных (многие записи с одинаковыми значениями MID) и EXPLAIN выводится впечатление, что вам не нужен индекс для mid (я считаю, mid_idx - это индекс для mid)потому что это недостаточно избирательно ...

1 голос
/ 03 августа 2011
ALTER TABLE `chapter` ADD INDEX `cindex_1` (`mid` ASC, `hitcount` ASC, `chapterno` DESC);
ALTER TABLE `chapter` ADD INDEX `cindex_2` (`mid` ASC, `chapterno` ASC, `hitcount` DESC);

Первый индекс оптимизирует основной запрос, а второй оптимизирует подзапрос.

1 голос
/ 03 августа 2011

Попробуйте создать индекс для Mid и ChapterNo. Возможно, даже на HitCount, но имейте в виду, что индексы снижают производительность при вставках / обновлениях, поэтому не создавайте индексы повсюду. Я бы сказал, начните с Mid, протестируйте, а затем создайте индекс для главы.

1 голос
/ 03 августа 2011

CREATE INDEX во всех трех из этих полей: t1.id, t1.hitcount, t1.chapterno

0 голосов
/ 03 августа 2011

Вот что я сделал:

SELECT c1.ID, c1.ChapterNo, c1.HitCount 
FROM chapter c1 JOIN (
SELECT ChapterNo, max(HitCount) max 
FROM chapter c2 
WHERE MID=2524 
GROUP BY ChapterNo) c3 
ON c1.ChapterNo=c3.ChapterNo AND c1.HitCount=c3.max;

С 2 индексами: один для ChapterNo, HitCount и один для MID

Возвращает мгновенно с 100k строк.

...