Я поигрался с ответами, данными мне здесь (которые я с тех пор проголосовал), и, исходя из их вдохновения, придумал запрос, который, кажется, выполняет работу с удивительно выдающейся производительностью:
SELECT r.* FROM recipes r
LEFT JOIN recipes_ingredients ri ON ri.parent_id = r.id
LEFT JOIN ingredients i ON i.id = ri.ingredient_id AND i.sweetness = 10
GROUP BY r.id HAVING MAX(i.id) IS NULL
Соединения с условием внутри (по вдохновению @Donnie) выявляют комбинации рецепт-ингредиент со строками NULL, если ингредиент не сладкий 10. Затем мы группируем по идентификатору рецепта и выбираем «максимальный» идентификатор ингредиента.(Функция MAX
будет возвращать ноль в том и только в том случае, если нет фактических идентификаторов для выбора, т. Е. Нет абсолютно никаких предметов не-сладости-10, связанных с этим рецептом, для выбора.) Если этот «максимальный» идентификатор ингредиентаnull, тогда не было элементов sweetness-10 для функции MAX для выбора, и поэтому выбираются строки HAVING
null MAX(i.id)
.
Я запустил обе версии NOT EXISTS
запросаи вышеупомянутая версия запроса несколько раз с отключенным кешированием запросов.По сравнению с примерно 400 рецептами, выполнение запроса NOT EXISTS
всегда занимало бы около 1,0 секунды, тогда как время выполнения этого запроса обычно составляло около 0,1 секунды.Для примерно 5000 рецептов запрос NOT EXISTS
занял около 30 секунд, тогда как вышеупомянутый запрос обычно занимал 0,1 секунды и почти всегда был ниже 1,0.
Стоит отметить, что при проверке EXPLAINs для каждого запросаПеречисленные здесь могут работать почти полностью по индексам, которые я дал этим таблицам, что, вероятно, объясняет, почему он может выполнять все виды объединения и группировки, не падая глазом.Запрос NOT EXISTS
, с другой стороны, должен выполнять зависимые подзапросы.Эти два показателя могли бы работать более равномерно, если бы эти индексы не были на месте, но этот оптимизатор запросов был бы чертовски мощным, если бы у него была возможность использовать необработанные объединения. Казалось бы,
Мораль истории: хорошо сформированныйСОЕДИНЕНИЯ супер-мощные :) Спасибо всем!