Что я сделал. Заменил три лефт-джойна на кросс-джойн с кейсом. Это иногда бывает быстрее лефт джойнов. Посмотрите, действительно ли будет прирост в скорости у вас и если да, то пользуйтесь.
У вас в запросе используется COUNT(d.id). Запрос скорее всего делает не то,что вы хотели, а возвращает одну строчку (потому что не указан GROUP BY). Если я прав, то для этого в моем варианте в подзапросе один раз вычисляется count и потом используется вычисленный cntAll.
Убрал LEFT JOIN nutrition_program_delivery oc ON oc.order_id = d.order_id, потому что он нигде не используется.
Переписал IN в JOIN. Mysql(по крайней мере 5.5) отвратительно оптимизирует IN, как правило, преобразовывая его в exists и вычисляя для каждой строки. Maria, например, так не делает.
Что еще можно сделать:
Убедиться, что по полям, по которым фильтруются данные есть индексы и по полям, по которым джойнятся таблицы - тоже есть индексы.
Переписать лефт-джойн в иннер-джойн, если он подходит по смыслу, такой запрос будет качественнее оптимизироваться самой СУБД.
Эээ. Вы доа=вольно своеобразно используете SQL. Я ваш запрос ен понимаю. И Mysql не поймет, хотя и вернет какие-то странные строки. Другие субд пошлют вас с таким запросом.
LIME пишет:
HAVING работает только с агрегирующими ф-циями
нет) С любым столбцом результирующего набора, получившимся после группирования и использования вычислимых столбцов. (Добавление)
Сейчас напишу немного теории, а потом немного практики (Добавление)
Как работает HAVING. Точнее, как работает запрос вообще. Сначала происходит фильтрация по условиям, указанным в WHERE и группировки. Здесь используются данные таблиц и индексов. После этого получается результирующий набор, который можно отфильтровать с помощью having. Это как будто взять в скобки наш первый запрос, написать перед скобками select * from, а после скобок where с тем условием, которое вы пытаетесь запихать в хэвинг. Попробуйте и осознаете, почему having price=min(price) не имеет особого смысла.
Теперь практика.
В mysql мы можем, например, так (в порятке предпочтения)
1. select * from tbl where price in (select min(price) from tbl union all select min(price) from tbl)
2. select * from tbl join (select min(price) minp, max(price)maxp from tbl) t ON price IN (maxp,minp)
3. Те же 2 запроса, но min и max можно заменить на order by asc/desc с limit 1 - это иногда быстрее.
4. Использовать переменную. Но это муторно, мне лень писать. Если только заинтересует.
5. Через not exists
В нек. ругих субд можно написать
select *, min(price) over(partition by Obj) minp, max(price) over(partition by Obj) maxp
from tbl
having price in (minp, maxp)
в select() нужно указать список столбцов, в котором ненужный user_id можно не перечислять.
Или поменять таблицы местами и сделать right join, тогда таблица справа всегда будет со значением, и user_id будет в итоге правый
float(3.1662002086639) float(2.857399892807) на короткой строке
float(3.5562990188599) float(2.9403080463409) на длинной
Та таком простеньком регулярка тоже проиграла. Но она удобнее читается)
Длина строки, время выполнения 1000000 итераций:
1. Искомая строка 5 символов близко к началу
int(3366) double(3.8106479644775) double(3.3490209579468)
2. Искомая строка 5 символов в конце (или вообще отсутствует)
int(3366) double(6.5905828475952) double(3.3512721347809)
3. Искомая строка находится ближе к концу, ее длина 1000 символов
int(3366) double(24.582785129547) double(2.3106808662415).
Последний случай - явление довольно редкое, а вот первые 2 показывают, что стрпоз сопоставим с регуляркой.
Но если слов больше и порядок тоже не имеет значения, то таким способом можно задолбаться писать.
Можно сделать так (я напишу на PHP, Вы переведете на свой язык):
preg_match_all('/(дайте|дадите|можно)|(админку|хелперку|хелпера)/', $src, $m);
а потом циклом проверить, чтоб все элементы $m[1] были не пустые.
Что будет работать быстрее - preg_match_all + цикл по совпадниям или цикл со стрпозами - вопрос спорный. Регулярка почти всегда быстрее двух стрпозов (если она выполняет то же самое, что планируется сделать двумя стрпозами). А если матчить точное совпадение, то она сопоставима по скорости со стрпозом.