Оптимизация инструкции SQL

#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. Спасибо. Это именно то, что я искал