#mysql #sql #sum #subquery #query-optimization
#mysql #sql #сумма #подзапрос #запрос-оптимизация
Вопрос:
Я пытаюсь выполнить SQL-запрос, который занимает много времени в mysql. Таблица очень большая (более 160000 строк). У меня есть структура таблицы ниже
id | clientID | type | price | code | created_at
Желаемый результат:
ldate | Cid | Total | Total2
В настоящее время я использую этот запрос:
select max(created_at) as ldate, clientID as Cid,
(SELECT SUM(price) as total from invoice
where clientID = Cid and type = 9 and code <> 0) as total,
(SELECT SUM(price) as total from invoice
where clientID = Cid and type = 9 ) as total2
from invoice
group by clientID
having max(created_at) < '2019-09-01'
Есть ли способ оптимизировать этот запрос для более быстрого выполнения или проблема связана только с большим количеством строк.
Есть предложения?
Комментарии:
1. Прочитайте некоторые из множества вопросов здесь по оптимизации запросов. Обратите особое внимание на те, за которые проголосовали и на которые были даны ответы. Сравните информацию, представленную в вопросах, с теми, которые отклонены / остались без ответа / закрыты. Сравните их с тем, что вы представили здесь. В вашем вопросе многого не хватает.
2. Пожалуйста, определите, что для вас означает «работать быстрее»? сколько времени выполняется этот конкретный запрос? насколько быстрее вы хотите? 160 000 строк — небольшая таблица, сравните с таблицами в хранилище данных.
3. Пожалуйста, поставьте псевдонимы для каждой ссылки на столбец; трудно отследить, какой столбец находится в каком экземпляре
invoice
.
Ответ №1:
Если я правильно понимаю цель вашего запроса, вы могли бы использовать условную агрегацию, а не скалярные подзапросы, поэтому таблица сканируется только один раз:
select
max(created_at) as ldate,
clientid as cid,
sum(case when type = 9 and code <> 0 then price else 0 end) as total,
sum(case when type = 9 then price else 0 end) as total2
from invoice
group by clientid
having max(created_at) < '2019-09-01'
Комментарии:
1. Спасибо. Это именно то, что я искал