Достаточно ли умен MySQL, чтобы не запрашивать повторно максимальную дату для каждого элемента?

#mysql

#mysql

Вопрос:

У меня есть запрос, который выполняет соединение, подобное этому:

 LEFT JOIN history ON history.item_id=item.id AND history.date=(SELECT MAX(date) FROM history WHERE item_id=item.id)
  

Достаточно ли умен MySQL, чтобы выполнить SELECT MAX... подзапрос только один раз?


Редактировать: Извините, я должен был упомянуть, что WHERE в целом SELECT указывается единственный идентификатор элемента:

 WHERE item.id=XXX
  

Комментарии:

1. Запрос будет кэшироваться, но поскольку подзапрос зависит от значений в родительском запросе, скорее всего, вы будете получать новое сканирование MAX () каждый раз, поскольку item_id будет меняться при каждом вызове подзапроса.

2. @Marc: Упс… следовало бы упомянуть, что общий ВЫБОР указывает item_id, поэтому он не отличается для каждого подзапроса. На самом деле.. подождите. Я думаю, что я облажался со всем этим вопросом. Однако суть в том, что условия были бы одинаковыми для каждой строки, иначе этот вопрос не имел бы смысла. Не удается кэшировать его, если значения были разными.

Ответ №1:

Короткий ответ — НЕТ.

Лучшая практика — использовать переменные

 SELECT @maxDate:= MAX(date) FROM history WHERE item_id=item.id
  

а затем использовать переменную @maxDate в ваших запросах.

Комментарии:

1. Возможно, это не по теме, но поддерживает ли это PHP? Если я выполню это сначала в одном mysql_query , я смогу использовать эту переменную в последующем запросе? На самом деле, это даже не имеет значения, потому что я мог бы просто использовать переменные PHP вместо этого…

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

3. @Mark: Да, вы можете, но это должно быть сделано с помощью того же дескриптора соединения в PHP, поскольку они предназначены для каждого соединения, а не для каждого пользователя.

Ответ №2:

explain plan Затем выполните запрос и посмотрите

Я собираюсь сказать «Нет», потому что это «коррелированный подзапрос»

смотрите: http://blog.sqlauthority.com/2007/09/07/sql-server-correlated-and-noncorrelated-subquery-introduction-explanation-and-example/

Я знаю, что СУБД в блоге — MSSQL, но применяется тот же принцип