Условие:
база данных содержит больше 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
Комментарии
так что все-таки повлияло, смена местами from и inner join, или use index?
конечно use index.
в первом случае mysql действует следующим образом,
оно берет таблицу node используя индекс отбирает все записи со статусом один коих конечно почти 60 000.
переносит результаты этой операции во временную таблицу, далее связывает с таблицей статисктикс комментариев, и начинает отбирать записи до момента накопления в LIMIT
во втором случае, я даю указание mysql взять индекс даты из комментс, которые как мы помним из условия задачи, лежат в памяти а уже потом связываться с node то есть тем самым я убиваю промежуточное создание временной таблицы.
если вас не затруднит, могли бы вы вывесить результаты выполнения запроса как на картинке http://drupal.ru/files/3_7.jpg только без строки "use undex"? Просто сам не имею возможности попробовать, нет такой большой БД, а интересно жутко -) Заранее спасибо.
Я понимаю Ваше недоверие )))) к тому насколько глубоко я понимаю как работает mysql потому вот вам без use index
то есть, как видим от перестановки слагаемых, без использования use index время запроса остается на старом уровне. то еcть 0.24
интересная инфа, спасибо. А что спрашиваю - в исходниках друпала я так и не нашел "USE INDEX", непонятно мне почему они такой ход нигде не использовали...
в тех случаях которые я лично отслеживал используются запросы где это не требуется.
Исключение составляет views с CCK там мрак полный.
к сожалению force index/use index осиливает только mysql (и еще кто-нить наверно)... да и в друпале есть hook_db_rewrite_sql, в результате которого where-часть может поменяться.
несмотря на это force index пользую...