MySQL Query Optimization - PullRequest
       11

MySQL Query Optimization

1 голос
/ 07 февраля 2011

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

CREATE TABLE `users` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(30) NOT NULL,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;

Вот мой запрос MySQL

 explain select article.id,users.username,article.title 
 from article,users,tags 
 where article.id=tags.article_id and tags.name = 'iphone4' 
 and article.author_id=users.id and article.status = '1' 
 and article.section = 'mobile' 
 and article.date > '2010-02-07 13:25:46' 
 ORDER BY tags.article_id DESC 


вывод

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra <br>
1   SIMPLE  tags    ref     PRIMARY     PRIMARY     92  const   55  Using where; Using index <br>
1   SIMPLE  article     eq_ref  PRIMARY     PRIMARY     4   test.tags.article_id    1   Using where <br>
1   SIMPLE  users   eq_ref  PRIMARY     PRIMARY     4   test.article.author_id  1     <br>

можно ли его оптимизировать больше?

Ответы [ 3 ]

0 голосов
/ 10 февраля 2011

Этот запрос может быть оптимизирован в зависимости от того, какое условие является более избирательным: tags.name = 'iphone4' или article.date > '2010-02-07 13:25:46'

Если статей с тегом iphone меньше, чем статей, опубликованных после Feb 7, тогда ваш исходный запрос хорош.

Если есть много статей с тегом iphone, но мало опубликованных после Feb 7, тогда этот запрос будет более эффективным:

SELECT  article.id, users.username, article.title
FROM    tags
JOIN    article
ON      article.id = tags.article_id
        AND article.status = '1'
        AND article.section = 'mobile'
        AND article.date > '2010-02-07 13:25:46'
JOIN    users
ON      users.id = article.author_id
WHERE   tags.name = 'iphone4'
ORDER BY
        tags.article_date DESC, tags.article_id DESC

Обратите внимание, что условие ORDER BY изменилось. Это может или не может быть тем, что вы хотите, однако, как правило, порядки id и date соответствуют друг другу.

Если вам действительно нужно ваше исходное ORDER BY условие, вы можете оставить его, но оно добавит filesort (или просто вернется к вашему первоначальному плану).

В любом случае создайте индекс для

article (status, section, date, id)
0 голосов
/ 10 февраля 2011

запрос должен выводить все открытые статьи о «iphone» за последний месяц.

Таким образом, единственный запрос, который вы собираетесь выполнить для этих данных, использует тег и дату.У вас есть индекс для тега в таблице тегов, но дата хранится в другой таблице (статья - вы немного не согласуетесь со своей схемой именования).Добавление индекса в таблицу статей с использованием даты не принесет никакой пользы.Использование id, date (в таком порядке) немного помогло бы - но на самом деле дату нужно денормализовать в таблицу тегов, чтобы запрос выполнялся действительно быстро.

Если вы регулярно не перемещаетесь вокруг больших массивов данных- просто добавьте в таблицу тегов столбец даты и времени по умолчанию с текущей отметкой времени.

Я ожидаю, что вы, возможно, захотите взаимодействовать с данными многими другими способами - на самом деле вам следует установить низкий уровень?) порог для медленной регистрации запросов, затем проанализируйте полученные данные, чтобы определить, где у вас проблемы с производительностью (попробуйте сначала просмотреть запросы с самыми высокими значениями для длительности ^ 2 * частота).

По указанному ниже URL-адресу есть скрипт, который полезен для этого анализа:

http://www.retards.org/projects/mysql/

0 голосов
/ 07 февраля 2011

Вы можете проиндексировать дополнительные поля в статье, на которую вы ссылаетесь в вашем операторе select.В этом случае я бы посоветовал вам создать индекс в статье следующим образом:

CREATE INDEX article_idx ON article (author_id, status, section, date);

Создание этого индекса должно ускорить ваш запрос в зависимости от общего количества записей, с которыми вы работаете.Насколько я понимаю, правильное создание индексов включает просмотр написанных вами запросов и индексацию столбцов, которые являются частью вашего предложения where.Это помогает оптимизатору запросов лучше обрабатывать запрос в целом.Однако это не означает создание индекса для каждого отдельного столбца, поскольку это неэффективно и неэффективно.Когда это возможно, создайте несколько индексов столбцов, которые представляют ваш оператор выбора.

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