MySQL запрос занимает> 15 секунд для выполнения; что я могу сделать, чтобы кэшировать / улучшить его? - PullRequest
1 голос
/ 07 декабря 2008

Ну, у меня есть веб-сайт с видео, и некоторые из его таблиц:

метка

id ~ int(11), auto-increment [PRIMARY KEY]
tag_name ~ varchar(255)

videotags

tag_id ~ int(11) [PRIMARY KEY]
video_id ~ int(11) [PRIMARY KEY]

видео

id ~ int(11), auto-increment [PRIMARY KEY]
video_name ~ varchar(255)

Теперь на этом этапе таблица тегов имеет> 1000 строк, а таблица видеотегов -> 32000 строк. Поэтому, когда я запускаю запрос, чтобы отобразить все теги от наиболее распространенных до наименее распространенных, требуется более 15 секунд.

Я использую PHP, и мой код (упрощенный) выглядит следующим образом:

foreach ($database->query("SELECT tag_name,COUNT(tag_id) AS 'tag_count' FROM tags LEFT OUTER JOIN videotags ON tags.id=videotags.tag_id GROUP BY tags.id ORDER BY tag_count DESC") as $tags)
{
    echo $tags["tag_name"] . ', ';
}

Теперь помните, что точность на 100% для меня не так важна, как быстрая. Поэтому, даже если запрос выполнялся один раз в день, а его результаты использовались до конца дня, мне было бы все равно.

Я абсолютно ничего не знаю о кешировании MySQL / PHP, поэтому, пожалуйста, помогите!

Ответы [ 4 ]

3 голосов
/ 07 декабря 2008

MarkR упомянул индекс. Убедитесь, что вы:

create index videotags_tag_id on videotags(tag_id);
2 голосов
/ 07 декабря 2008

32 000 строк - это все еще небольшая таблица - ваша производительность не должна быть такой плохой.

Можете ли вы запустить EXPLAIN по вашему запросу - я думаю, что ваши индексы где-то не так.

Вы говорите в вопросе:

tag_id ~ int(11) [PRIMARY KEY]
video_id ~ int(11) [PRIMARY KEY]

Они определенно в таком порядке? Если нет, то он не будет использовать индекс.

0 голосов
/ 07 декабря 2008

Используете ли вы InnoDB или MyISAM? В MyISAM COUNT в основном бесплатен, но в InnoDB он должен физически считать строки.

0 голосов
/ 07 декабря 2008

Я думаю, что вам лучше всего создать сводную таблицу, которую вы будете вести, когда все изменится.

В приведенном выше запросе необходимо отсканировать все строки в таблице, чтобы найти агрегаты в группе - НЕТ ОТВЕТА ГДЕ. Запрос без условия where не имеет надежды на оптимизацию, поскольку он обязательно должен проверять каждую строку.

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

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

Когда вы делаете соединение, правильные индексы все еще полезны, но вы знали об этом, верно, и уже сделали это?

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