к вопросу о оптимизации или небольшая задачка(с последующим решением) по my sql

Главные вкладки

Аватар пользователя Demimurych Demimurych 7 октября 2009 в 18:08

Условие:
база данных содержит больше 100 000 нод. mysql сервер сконфигурирован таким образом что все индексы находятся в памяти.

Задача:
Выбрать nid всех нод статус которых 1 в порядке добавления последнего комментария.

Решение вроде бы тривиально

SELECT n.nid FROM node n
INNER JOIN node_comment_statistics ncs on n.nid = ncs.nid
WHERE n.status = 1 ORDER BY ncs.last_comment_timestamp DESC

индексы на status и last_comment_timestamp присутствуют.
однако, такой запрос будет выполняться 0.24 секунды на поиске первых 30 записей, и все дольше и дольше с каждой следующей пачкой.

Этот запрос можно привести к виду при котором он будет выполняться 0.001 секунды независимо от пачки.

Отгадка на картинке номер 3

ВложениеРазмер
Иконка изображения 1.jpg15.81 КБ
Иконка изображения 2.jpg41.86 КБ
Иконка изображения 3.jpg19.43 КБ

Комментарии

Аватар пользователя Demimurych Demimurych 10 ноября 2015 в 11:46

"kosilko" wrote:
так что все-таки повлияло, смена местами from и inner join, или use index?

конечно use index.

в первом случае mysql действует следующим образом,

оно берет таблицу node используя индекс отбирает все записи со статусом один коих конечно почти 60 000.
переносит результаты этой операции во временную таблицу, далее связывает с таблицей статисктикс комментариев, и начинает отбирать записи до момента накопления в LIMIT

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

Аватар пользователя kosilko kosilko 7 октября 2009 в 19:42

если вас не затруднит, могли бы вы вывесить результаты выполнения запроса как на картинке http://drupal.ru/files/3_7.jpg только без строки "use undex"? Просто сам не имею возможности попробовать, нет такой большой БД, а интересно жутко -) Заранее спасибо.

Аватар пользователя Demimurych Demimurych 10 ноября 2015 в 11:46

"kosilko" wrote:
если вас не затруднит, могли бы вы вывесить результаты выполнения запроса как на картинке http://drupal.ru/files/3_7.jpg только без строки "use undex"? Просто сам не имею возможности попробовать, нет такой большой БД, а интересно жутко -) Заранее спасибо.

Я понимаю Ваше недоверие )))) к тому насколько глубоко я понимаю как работает mysql потому вот вам без use index

то есть, как видим от перестановки слагаемых, без использования use index время запроса остается на старом уровне. то еcть 0.24

Аватар пользователя kosilko kosilko 7 октября 2009 в 20:50

интересная инфа, спасибо. А что спрашиваю - в исходниках друпала я так и не нашел "USE INDEX", непонятно мне почему они такой ход нигде не использовали...

Аватар пользователя Demimurych Demimurych 7 октября 2009 в 21:05

"kosilko" wrote:
интересная инфа, спасибо. А что спрашиваю - в исходниках друпала я так и не нашел

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

Исключение составляет views с CCK там мрак полный.

Аватар пользователя zhylik zhylik 8 октября 2009 в 11:35

"kosilko" wrote:
в исходниках друпала

к сожалению force index/use index осиливает только mysql (и еще кто-нить наверно)... да и в друпале есть hook_db_rewrite_sql, в результате которого where-часть может поменяться.

несмотря на это force index пользую...